TSQL存储过程的参数错误
如果我有这个存储过程定义减去身体TSQL存储过程的参数错误
ALTER PROCEDURE sp_AlloctionReport(@where NVARCHAR(1000), @alldate NVARCHAR(200), @alldateprevweek NVARCHAR(200))
AS
我呼吁这个样子。
sp_AllocationReport "ProductCode = 'FA' AND AllocationDate = '20090112' AND VenueInfo.VenueID In(SELECT vf.VenueID FROM VenueFilters vf INNER JOIN FilterTypes ft ON vf.FilterTypeID = ft.FilterTypeID WHERE ft.FilterDescription = 'Coke') AND State = 'NSW'","CampaignAllocations.AllocationDate = '20090112'","CampaignAllocations.AllocationDate = '20090105'"
当我的第一个参数定义为NVARCHAR(1000)时,为什么会出现此错误。
以 '的ProductCode = 'FA' AND AllocationDate = '20090112' AND VenueInfo.VenueID IN(SELECT vf.VenueID FROM VenueFilters VF INNER JOIN网络连接' 太长。最大长度是开始标识符128
- 以where子句,并在一个新的文件
- '与 '替换' 编辑(单引号 - >双单引号)
EXEC dbo.sp_AllocationReport @where= '<THE TEXT EDITED ABOVE>'
- 检查双引号“可乐”。语法highligher使误差明显。
- 使用单引号主弦,和双逃脱他们需要的地方。是的,这是一个痛苦,但它是正确的方式做它
- 前缀NVarchar文字与大写N
- 这是一个SQL注入攻击等待发生的气味。你确定你需要作为字符串变量传递SQL吗?
的最大长度一个对象在SQL服务器128字符(我认为)。在编译查询时,可能是一个语法问题,它认为整个字符串是一个表/视图名称?
您必须使用单引号代替双引号,除非连接已QUOTED_IDENTIFIER开启
http://msdn.microsoft.com/en-us/library/ms174393.aspx
这是从SQL 2000年开始的默认,但如果你从旧版本升级,那么旧的默认值仍然有效。
如果我们有存储过程的主体,它可能会更清晰。但是......看起来像是SQL Server将您的参数解释为一个indentifer(即列名称)。线索是错误信息,其中指出“以'ProductCode ='FA'AND [...]开头的标识符太长”。即,SQL Server正在寻找一个列命名为“产品代码=‘FA’和[...等等...]”
所以我怀疑是你的存储过程中做到了这:
SELECT col1, col2, col3, ... FROM table WHERE @where
...和你希望where子句工作就像那样。
假设这是你所做的,它将无法工作。如果这不是你所做的,这个答案的其余部分可能完全是假的:-)如果你可以给出一个sproc主体的例子,它可能会让事情变得更加清晰。
因此,假如我suspision是正确的,你需要把它写成一个动态SQL语句是这样的:
DECLARE @sql NVARCHAR(2000)
SET @sql = 'SELECT col1, col2, col3, ... FROM table WHERE ' + @where
EXEC sp_ExecuteSQL @sql
无论其 ......即使这不是故事的结尾这很容易发生注入攻击,这是a very bad thing。你最好做的是改变params到你存储的proc中,以利用参数化的SQL,这不会容易发生注入攻击。像这样...
ALTER PROCEDURE sp_AllocationReport (@ProductCode VARCHAR(10), @AllocationDate DATETIME, {rest of your parameters})
AS
DECLARE @sql NVARCHAR(2000)
SET @sql = 'SELECT col1, col2, col3, ... FROM table WHERE 1 = 1'
IF ISNULL(@ProductCode, '') <> ''
SET @sql = @sql + ' AND ProductCode = @pProductCode'
IF @AllocationDate IS NOT NULL
SET @sql = @sql + ' AND AllocationDate = @pAllocationDate'
{other conditionals, depending on what you need to pass in}
EXEC sp_ExecuteSQL @sql, '@pProductCode VARCHAR(10),
@pAllocationDate DATETIME,
{other passed in params}
', @ProductCode, @AllocationDate
此代码不容易发生注入式攻击。由于SQL Server会更可靠地缓存执行计划,因此它也更具性能。了解这一点;这里有很多。
我试过用单引号,但给出了相同的错误。这是一个Access前端应用程序内部,所以它可以使用字符串。 – Malcolm 2009-09-04 03:51:02
没错。没关系,因为内部员工从不做坏事。祝你好运。 – 2009-09-04 12:16:46