【问题标题】:Executing procedure with varchar parameter, passed into OPENROWSET, error使用 varchar 参数执行过程,传递给 OPENROWSET,错误
【发布时间】:2021-08-13 13:02:14
【问题描述】:

我正在处理使用OPENROWSET 的程序。 我需要将 1 个 varchar 参数传递给它。这就是我决定这样做的方式:

ALTER PROCEDURE [dbo].[GetId]
@designatio varchar
AS
BEGIN
DECLARE @SQLStr varchar(max)=
    'select * FROM OPENROWSET(''SQLOLEDB'',''SQLSERVER'';''sss'';''sss''
    ,''select *
        from db.dbo.table)
        where DESIGNATIO = ''' + @designatio + ')'

EXECUTE(@SQLStr)
END

一切正常,但执行时出错:

exec GetId 'П-11792.00'

“П”附近的语法不正确

我尝试过强制转换传递参数,所以错误是一样的,但是

'П-11792.00' 附近的语法不正确

请告诉我,我哪里错了。

【问题讨论】:

  • 过程声明是GetId,而你给出的例子是GetSearchId,是不是打错字了?
  • @FilipeNóbrega 是的,很抱歉)
  • 您没有足够的报价单。请记住,OPENROWSET 中的查询本身是引用的,并且您正在动态构建它,因此您需要四个引号来获得两个引号,以便在最终查询中以一个引号结束。 (而且您缺少结束引号。)始终尝试分层构建查询,自下而上,随着您的升级,系统地替换引号。这样你就不会不小心错过一个。 PRINTing 你构建的东西也总是一个好主意。
  • 另外,在可能的情况下,看看EXECUTE .. AT 是否带有链接服务器是一种选择,因为与OPENROWSET 不同,它支持参数(EXECUTE ('SELECT * FROM db.dbo.table WHERE DESIGNATIO = ?', @designatio) AT LinkedServerName),省去了一大堆引用的麻烦。
  • @designatio varchar 这是一个单一的字符参数 - 一个常见的错误。始终定义任何可变长度数据类型的长度。

标签: sql-server tsql dynamic-sql


【解决方案1】:
ALTER PROCEDURE [dbo].[GetId]
@designatio varchar
AS
BEGIN
DECLARE @SQLStr varchar(max)=
    'select * FROM OPENROWSET(''SQLOLEDB'',''SQLSERVER'';''sss'';''sss''
    ,''select *
        from db.dbo.table)
        where DESIGNATIO = ''''' + @designatio + ''''' '')'

EXECUTE(@SQLStr)
END

问题在于理解,查询中的字符串值必须有自己的引号,所以如果它已经在双引号中,它必须是4个引号+自己的引号。

【讨论】:

  • 请注意,如果您传递多个字符的@designation,这仍然会(默默地)失败,请务必更正。这是bad habit to kick。
  • 哦,谢谢,我明白了。我已经以这种观点发布了该程序,因为在我决定询问之前已经进行了很多尝试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-16
  • 2014-03-29
  • 1970-01-01
  • 1970-01-01
  • 2016-10-03
  • 1970-01-01
相关资源
最近更新 更多