经典ASP从SQL2005获取SCOPE_IDENTITY()值

经典ASP从SQL2005获取SCOPE_IDENTITY()值

问题描述:

我无法弄清楚如何从SQL2005存储过程中将SCOPE_IDENTITY()返回给我的变量。经典ASP从SQL2005获取SCOPE_IDENTITY()值

我sSQL字符串:

sSQL = "EXEC [sp_NewClaim] " & Chr(34) & ClaimNumber & Chr(34) & ", " & Request.Cookies("UserID") & ", " & Request.Cookies("MasterID") & ", " & Chr(34) & strRestaurante & Chr(34) & ", " & Chr(34) & Fecha & Chr(34) & ", " & Chr(34) & Hora & Chr(34) & ", " & Chr(34) & Request("Tiempo") & Chr(34) & ", " & Chr(34) & Request("Luz") & Chr(34) & ", " & Chr(34) & Request("Desc") & Chr(34) & ", " & Chr(34) & Request("incidente") & Chr(34) & ", " & Chr(34) & Request("codigos") & Chr(34) & ", False, 0; SELECT RecordNumber = SCOPE_IDENTITY()" 

我sSQL输出:

EXEC [sp_NewClaim] "W200811", 7, 8, "Otro -- WORK PLEASE", "11/19/2008", "01:19 PM", "Nublado", "Mala", "asdasd", "uyiuyui", "C-Junta", False, 0; SELECT RecordNumber = SCOPE_IDENTITY() 

执行我的SQL命令:

Set rsData= Server.CreateObject("ADODB.Recordset") 
rsData.Open sSQL, conDB, adOpenKeyset, adLockOptimistic 

试图输出SCOPE_IDENTITY()产生空变量(无输出):

Response.Write("<br />Record Number: " & rsData("RecordNumber")) 

存储过程运行正常。我的信息被保存到我的数据库中,出现问题。 RecordNumber与身份列,和存储过程定义@RecordNumber作为输出:

USE [db_clcinsurance_com] 
GO 

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE PROCEDURE sp_NewClaim 
(
    @ClaimNumber nvarchar(50), 
    @blah............ 
    ................. 
    @RecordNumber INT OUTPUT 
    ) 
AS 

BEGIN 

    INSERT INTO Accidente (ClaimNumber,........., RecordNumber) 

    VALUES (@ClaimNumber,....., @RecordNumber) 

    SET @RecordNumber = SCOPE_IDENTITY(); 

END 
+0

我希望这只是示例代码,查找SQL注入;) – Ryan 2008-11-20 05:15:21

为您的存储过程,这样做:

CREATE PROCEDURE sp_NewClaim 
(
    @ClaimNumber nvarchar(50), 
    @blah............ 
    ................. 
) 
AS 
BEGIN 
    SET NOCOUNT ON; 

    INSERT INTO Accidente (ClaimNumber,........., RecordNumber) 
     VALUES (@ClaimNumber,....., @RecordNumber) 

    SELECT SCOPE_IDENTITY() 
END 

然后拿到ID以同样的方式你会检索任何其他查询结果。

您可以尝试测试以确保SCOPE_IDENTITY()函数按预期工作 - 将SELECT @RecordNumber添加到存储区末尾,然后在Management Studio中手动运行它,以确认变量已按照您期望的方式设置。如果这不起作用,请尝试SELECT SCOPE_IDENTITY()以确认它在工作。最后,将变量值硬编码为测试,以确保OUTPUT参数正常工作。

Asp classic并不是我的强项,但思路是一致的。

问题是您没有将身份作为记录集返回,而是作为OUT参数返回。这意味着您尝试阅读的方式不正确。

尝试乔尔的建议,或通过返回代码得到它:

Return Scope_Identity() 

另外,您应该使用参数建立你的查询,并在指定的最后一个作为OUT参数。然后执行查询并检查最后一个参数的值。在.NET中,这将是(根据需要转换为VB):

SqlCommand cmd = new SqlCommand("INSERT INTO Foo (Description) VALUES (@Description); SET @Result = SCOPE_IDENTITY()"); 
SqlParameter paramDesc = new SqlParameter("@Description", SqlDbType.Int); 
cmd.Parameters.Add(paramDesc); 
SqlParameter paramResult = new SqlParameter("@Result", SqlDbType.Int); 
paramResult.Direction = ParameterDirection.Output; 
cmd.Parameters.Add(paramResult); 

我希望你做输入的一些擦洗,因为他们查询的方法是很容易出现SQL注入攻击。

Rob。

+0

我HTML编码器已被迫这个ASP的东西。所以,当你说这很容易SQL注入可以给我一个如何工作的例子吗?我得到了附加查询来删除表或1 = 1的一般IDEA,但我怎么能保护这个存储过程呢? – jesusOmar 2008-11-20 13:34:14

我同意Joel Coehoorn的回应,但我想说明您将发送您的SCOPE_IDENTITY()变量作为输出参数,但不会在您的ado调用中以这种方式检索它。您无法使用您要调用存储过程的方法来检索输出参数。

如果您好奇,有一些ado示例here来调用存储过程。

我同意罗伯特。如果要在存储过程中使用输出参数并使用动态SQL调用它,则在组装时,必须将SQL变量分配给输出参数,然后选择该变量。如分配SQL变量时,你也必须使用OUTPUT关键字:

sSQL = "DECLARE @RecNo int; EXEC [sp_NewClaim] 'param1', 'param2', etc..... @RecNo OUTPUT; SELECT @RecNo;"