Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Stored procedures ASP Classic-记录集对象与命令对象_Stored Procedures_Asp Classic_Sql Server 2000_Sql Injection - Fatal编程技术网

Stored procedures ASP Classic-记录集对象与命令对象

Stored procedures ASP Classic-记录集对象与命令对象,stored-procedures,asp-classic,sql-server-2000,sql-injection,Stored Procedures,Asp Classic,Sql Server 2000,Sql Injection,我正在使用ASP Classic和SQL Server 2000创建动态网站 在查询数据库时,我对何时使用记录集对象以及何时使用命令对象感到有点困惑 我被告知,如果存储过程将从SELCT语句返回记录,那么我应该使用记录集,但是如果我正在更新或插入,那么我应该使用命令对象并将所有数据作为参数传递给存储过程 使用记录集时,我通常会传递任何必需的数据,如: rs.Source = "spTest " & id 我总是验证我传递的数据,以确保它是我所期望的,并将其转换为正确的类型 但是,我

我正在使用ASP Classic和SQL Server 2000创建动态网站

在查询数据库时,我对何时使用记录集对象以及何时使用命令对象感到有点困惑

我被告知,如果存储过程将从SELCT语句返回记录,那么我应该使用记录集,但是如果我正在更新或插入,那么我应该使用命令对象并将所有数据作为参数传递给存储过程

使用记录集时,我通常会传递任何必需的数据,如:

rs.Source = "spTest "   & id
我总是验证我传递的数据,以确保它是我所期望的,并将其转换为正确的类型

但是,我后来被告知,上述方法使我的代码容易受到SQL注入攻击,我应该始终使用command对象

这是正确的吗

谢谢

是的,没错

想象有人传递字符串:“0;从用户中删除*

您的查询将是:

spTest 0; delete * from users;
如果幸运的话,您将没有用户表。就我个人而言,为了保持一致性,我会一直使用command对象。你可以从中得到你需要的一切

下面是一个如何使用command对象执行此操作的快速示例:

    Dim oStoredProc : Set oStoredProc = Server.CreateObject("ADODB.Command")

    With oStoredProc
        .ActiveConnection = oDBConnection
        .CommandType = adCmdStoredProc
        .CommandText = "up_procname"
        .Parameters.Append(.CreateParameter("@Param1", ADODB.adInteger, ADODB.adParamInput, 22, 11))
        .Parameters.Append(.CreateParameter("@Param2", ADODB.adInteger, ADODB.adParamOutput, 22, 12)

        Call .Execute()

        myVal = .Parameters("@Param2")
    End With

    Set oStoredProc = Nothing

您被告知的事实是正确的:您应该始终使用commande对象来防止SQL注入。使用参数化查询,您将所有参数的安全性和验证留给ADO层(尽管您仍然应该自己进行适当的验证),甚至可以获得一些性能改进(这些参数化查询由SQL Server缓存)

执行命令时,有两个选项:要么执行的SQL返回行(SELECT语句或某些存储过程),要么使用记录集存储这些行,要么不使用记录集(更新、删除、其他过程),然后只执行命令,而不必担心记录集

编辑:为了确保您对所有内容都很清楚,我使用了上面的James Wiseman代码,并将其改编为您的示例:

Dim oStoredProc : Set oStoredProc = Server.CreateObject("ADODB.Command")

With oStoredProc
    .ActiveConnection = oDBConnection
    .CommandType = adCmdStoredProc
    .CommandText = "spTest ?"
    .Parameters.Append(.CreateParameter("id", ADODB.adInteger, ADODB.adParamInput, id, 11))
    Dim rs : Set rs = .Execute()
End With

Set oStoredProc = Nothing
没有测试它,但应该可以:-)


最后但并非最不重要的一点:尽管您现在受到了很好的保护,但不要忘记,如果您在存储过程中使用动态SQL,您可能仍然存在SQL注入安全漏洞(我想说,只要您连接字符串以创建SQL,您就可能容易受到攻击)

谢谢。比如说,就像我给出的例子一样,我知道参数将是数值的,并且我已经验证了输入以确保它是数值的。是否可以使用我描述的记录集对象,还是应该使用命令对象?我只是问了很多时间,我通过的只是数值,如果我不需要全部通过并改变它们,这将节省我很多时间。谢谢,谢谢。那么,我应该只将记录集对象与命令对象结合使用吗?我还假设在运行不需要向其传递任何参数的存储过程时,可以使用recordset对象?感谢为了让事情变得更简单,我鼓励你们总是使用相同的方法:只要总是使用命令对象的记录集,就不用再考虑它了。有时您可能需要输入更多的代码,但使用一些可以编写的助手函数可以很容易地避免这种情况(您很快就会看到哪些代码总是重复)