SQL Server存储过程很糟糕

时间:2017-03-17 05:46:39

标签: sql sql-server

有人可以帮助我动态搜索存储过程吗?

这是我的存储过程:

 DECLARE mycursorForCountry CURSOR FOR
    SELECT CountryNames 
    FROM [Countries].[dbo].[World] 
    WHERE UserID = @userID

    OPEN mycursorForCountry

    FETCH NEXT FROM mycursorForCountry INTO @CountryNames

    WHILE (@@FETCH_STATUS = 0)
    BEGIN
        INSERT INTO @CountryTbl
           SELECT DISTCINT * 
           FROM ufn_Split((@CountryNames),',')

        FETCH NEXT FROM mycursorForCountry INTO @CountryNames
    END

    CLOSE mycursorForCountry
    DEALLOCATE mycursorForCountry

    DECLARE @SQL nvarchar(MAX)
    SET @SQL = 'SELECT * FROM [Information].[dbo].[Media] WHERE Country_Name IN('+@CountryNames+')'

    EXEC sp_executesql @SQL

我收到了一个错误:

  

Msg 102,Level 15,State 1,Line 260
  'AFRICA'附近的语法不正确

1 个答案:

答案 0 :(得分:2)

该行:

set @SQL = 'SELECT * FROM [Information].[dbo].[Media] WHERE  
  Country_Name IN('+@CountryNames+')'

未将@CountryNames返回的值包装在单引号中。将其更改为以下内容(使用两个单引号将其转义为单个引号):

set @SQL = 'SELECT * FROM [Information].[dbo].[Media] WHERE  
  Country_Name IN('''+@CountryNames+''')' 
  --              ^-------------------^------- added two single-quotes 

建议

当您以这种方式动态创建SQL语句时,请使用print @SQL打印出SQL语句以进行调试,以排除故障。如果你这样做了,你会注意到@SQL的内容是以下不正确的查询:

SELECT * FROM [Information].[dbo].[Media] WHERE Country_Name IN (AFRICA) 

那会告诉你,你在IN语句中有一个没有用引号括起来的字符串。

编辑:要正确生成以逗号分隔的国家/地区列表

DECLARE @CountryNames NVARCHAR(MAX) 

SET @CountryNames = (SELECT  '''' + CountryNames + ''',' 
FROM [Countries].[dbo].[World] 
WHERE UserID = @userID 
FOR XML PATH('') )

PRINT substring(@CountryNames, 1, len(@CountryNames) - 1) 

FOR XML PATH('')将单独的行连接成一行以逗号分隔的值,substring()函数用于删除尾随的逗号。

这避免了循环游标以形成逗号分隔列表的需要。

在这种情况下,不需要在@SQL变量的形成中插入两个单引号,因为所有必需的双引号都在上面的语句本身中形成。

编辑2:修改SQL

以下是完成您需要的SQL。请注意,它不使用游标,也不使用表@CountryTbl

DECLARE @CountryNames NVARCHAR(MAX) 

-- Prepares a comma-separated list of countries, e.g.: 'Africa','Nigeria', 
-- Note that there is a trailing comma 
SET @CountryNames = (SELECT  '''' + CountryNames + ''',' 
    FROM [Countries].[dbo].[World] 
    WHERE UserID = @userID 
    FOR XML PATH('') )

-- Remove the trailing comma 
SET @CountryNames = substring(@CountryNames, 1, len(@CountryNames) - 1) 

DECLARE @SQL nvarchar(MAX)
SET @SQL = 'SELECT * FROM [Information].[dbo].[Media] WHERE Country_Name IN('+ @CountryNames +')'

EXEC sp_executesql @SQL