2009-08-19 85 views
1

这是我的存储过程:MS SQL Server存储过程错误“不正确的语法”

ALTER PROCEDURE its.sp_WriteTransaction 

    (
    @LoginID int, 
    @PersonID int, 
    @BusinessID int, 
    @TransType smallint, 
    @LastHost varchar(15), 
    @TransData varchar(255) 
) 

AS 

DECLARE @TransDate DATETIME 
SET @TransDate = GETDATE() 

INSERT INTO Transactions (LoginID, PersonID, BusinessID, TransDate, TransType, LastHost, TransData) 
VALUES (@LoginID, @PersonID, @BusinessID, @TransDate, @TransType, @LastHost, @TransData) 
RETURN 

这是我的电话线:

sql = "sp_WriteTransaction" & " " & Session("UserID") & "," & Session("PersonID") & "," & Session("bizID") & "," & TransType & "," & ClientIP & "," & TransData 

但每次我运行它,我得到以下错误信息:

错误消息:

错误类型: 微软OLE SQL Server的数据库提供程序(0x80040E14) 第1行:“.0”附近的语法不正确。 /etearsheets/authorize/CheckAccess.asp,line 1163

导致'.0'错误的IP格式有什么问题,我该如何纠正它?

感谢R.

+1

**不要一直使用**使用“sp_”作为存储的参数名称前缀!如果你这样做的话,微软很生气!这是一个微软保留的前缀,如果你真的使用它,你只是要求麻烦!使用“proc_”或别的东西 - 或根本没有前缀。 – 2009-08-19 05:11:28

+0

实际上我没有选择,我正在根据公司文档构建这些存储过程,并且'sp_'问题与SQL Server 7.0 Service Pack 4有关,我们在V.09.00.3042上。不过谢谢你的提升,我会记住。 – flavour404 2009-08-19 19:50:43

+0

此代码易受sql注入影响 – 2011-12-01 19:42:29

回答

2

您还没有包括报价为您varchar列。

试试这个:

sql = "sp_WriteTransaction" & " " & Session("UserID") & "," & _ 
    Session("PersonID") & "," & Session("bizID") & "," & _ 
    TransType & ",'" & ClientIP & "','" & TransData & "'" 

它的失败了的IP地址,因为127.0.0.1不是数字。您目前正在尝试将其作为浮点数传递,该浮点数只使用一位小数。将其包含在单引号中会强制SQL将其解析为字符串。

+5

虽然正确,但我不能为此投票,因为它不使用查询参数,因此可能容易受到注入攻击。大部分这些值可能会让你失望,但TransData从哪里来? – 2009-08-19 03:18:48

+1

@Joel:我没有进入SQL注入式谈话,因为这看起来都是系统数据,但你确实提出了一个很好的观点。 – Eric 2009-08-19 03:25:05

+0

好的你是对的,大部分使用的数据都是系统数据。此外,是的,我知道系统中存在安全漏洞,我已经告诉客户,但他们似乎不愿意听b)不想付钱来分类,所以我尝试“适合”事情当我遇到他们但除此之外,我被支付给'使其工作',虽然我有时只是知道会发生什么事而畏缩。 – flavour404 2009-08-19 19:40:57

1

您需要在ClientIP值附近放置单引号。

1

像其他人说的,你不是单引号参数。

假设...

Session("UserID") = 0000 
Session("PersonID") = 4321 
Session("bizID") = 1234 
TransType = "GET" 
ClientIP = "192.168.1.1" 
TransData = "xyz" 

然后执行以下操作...

sql = "sp_WriteTransaction" & " " & Session("UserID") & "," & Session("PersonID") & "," & Session("bizID") & "," & TransType & "," & ClientIP & "," & TransData 
response.write(sql) 

会产生...

sp_WriteTransaction 0,4321,1234,GET, 192.168.1.1,xyz

更麻烦的是您将未编码的字符串传递给SQL,因为这会让您容易受到SQL注入攻击。在这种情况下,它看起来像数据可能都来源于没有客户来源,但考虑到你的问题的性质/天真,我怀疑你可能在其他地方是脆弱的。

这里是如何保护您的SQL

Session("UserID") = 11111 
Session("PersonID") = 4321 
Session("bizID") = 1234 
TransType = "GET" 
ClientIP = "192.168.1.1" 
TransData = "xyz" 

sql = "sp_WriteTransaction {0},{1},{2},{3},{4},{5}" 
parameters = Array(Session("UserID"),Session("PersonID"),Session("bizID"),TransType,ClientIP,TransData) 

Function BuildSQL(query, params) 
    Dim result : result = query 

    If Not IsArray(params) Then 
     BuildSQL = Null 
     Exit Function 
    End If 

    Dim i 
    For i = lbound(params) to ubound(params) 
     result = replace(result,"{" & i & "}",SQLEncode(params(i))) 
    Next 

    BuildSQL = result 
End Function 

Function SQLEncode (uVar) 
    If IsNull(uVar) Then 
     SQLEncode = "null" 
    Else 
     SQLEncode = "'" & replace(uVar,"'","''") & "'" 
    End If 
End Function 

Response.Write BuildSQL("sp_WriteTransaction {0},{1},{2},{3},{4},{5}",parameters) 

此代码输出下面的一个例子...

sp_WriteTransaction '11111', '4321', '1234',” GET '' 192.168.1。1' ,‘某某’

你可以采取这种通过把SQLEncode和BuildSQL到他们自己的文件DataAccess.inc并使其可在您所有的ASP文件与包括声明更进了一步。

例如

<!-- #include file="DataAccess.inc"--> 

要做到这一点,你需要有服务器端包含在IIS中启用,并确保在#include语句的相对路径是正确的。

+0

使用参数化SQL会更安全,更容易,而不是试图自己编码字段。 – LukeH 2009-08-19 08:51:14

+0

@Luke:我不知道你可以在Classic ASP中做参数化的SQL。 – MyItchyChin 2009-08-19 12:39:56

+1

@CptSkippy:你可以做到。看看http://msdn.microsoft.com/en-us/library/ms675101(VS.85).aspx – LukeH 2009-08-19 21:46:03