代码之家  ›  专栏  ›  技术社区  ›  Thakur

存储过程语法错误(MSSQL)

  •  5
  • Thakur  · 技术社区  · 15 年前

    下面提到的存储过程在创建时出错

    Msg 156, Level 15, State 1, Procedure crosstab, Line 23
    Incorrect syntax near the keyword 'pivot'.
    

    谁能告诉我这个错误吗?

    下面是脚本:

    CREATE PROCEDURE crosstab 
    @select varchar(8000),
    @sumfunc varchar(100), 
    @pivot varchar(100), 
    @table varchar(100) 
    AS
    
    DECLARE @sql varchar(8000), @delim varchar(1)
    SET NOCOUNT ON
    SET ANSI_WARNINGS OFF
    
    EXEC ('SELECT ' + @pivot + ' AS pivot INTO ##pivot FROM ' + @table + ' WHERE 1=2')
    EXEC ('INSERT INTO ##pivot SELECT DISTINCT ' + @pivot + ' FROM ' + @table + ' WHERE ' 
    + @pivot + ' Is Not Null')
    
    SELECT @sql='',  @sumfunc=stuff(@sumfunc, len(@sumfunc), 1, ' END)' )
    
    SELECT @delim=CASE Sign( CharIndex('char', data_type)+CharIndex('date', data_type) ) 
    WHEN 0 THEN '' ELSE '''' END 
    FROM tempdb.information_schema.columns 
    WHERE table_name='##pivot' AND column_name='pivot'
    
    SELECT @sql=@sql + '''' + convert(varchar(100), pivot) + ''' = ' + 
    stuff(@sumfunc,charindex( '(', @sumfunc )+1, 0, ' CASE ' + @pivot + ' WHEN ' 
    + @delim + convert(varchar(100), pivot) + @delim + ' THEN ' ) + ', ' FROM ##pivot
    
    DROP TABLE ##pivot
    
    SELECT @sql=left(@sql, len(@sql)-1)
    SELECT @select=stuff(@select, charindex(' FROM ', @select)+1, 0, ', ' + @sql + ' ')
    
    EXEC (@select)
    SET ANSI_WARNINGS ON
    
    2 回复  |  直到 15 年前
        1
  •  6
  •   Martin Smith    15 年前

    这看起来像是最初用于SQLServer2000的过程 pivot 不是关键字。将下面的部分更改为使用 [pivot]

    SELECT @sql=@sql + '''' + convert(varchar(100), [pivot]) + ''' = ' + 
    stuff(@sumfunc,charindex( '(', @sumfunc )+1, 0, ' CASE ' + @pivot + ' WHEN ' 
    + @delim + convert(varchar(100), [pivot]) + @delim + ' THEN ' ) + ', ' FROM ##pivot
    

    你也应该用 sysname 的数据类型 @table quotename 函数,并使用nvarchar而不是varchar。

    这些都是旨在减少SQL注入可能性以及允许您处理非标准对象名称的建议。目前 nvarchar(128) . 通过使用 系统名 而不是 但是如果在将来的版本中发生更改,则不必更新该过程。

    使用 varchar(100) 意味着您的过程将无法处理超过100个字符的(有效)对象名称。以及无法处理包含非标准字符的有效名称。

    is allowed in SQL Server

    CREATE TABLE "╚╦╩╗" ( "└┬┴┐" nvarchar(10)) 
    

    即使只使用ASCII字符命名表和列,将参数和变量保留为unicode也可以防止诸如 ʼ

    引号名称 将确保如果有任何列 Robert'); DROP TABLE Students; 这些被正确地转义为 [Robert'); DROP TABLE Students;] 以及处理对象名称中嵌入的方括号。

        2
  •  3
  •   Joe Ratzer    15 年前
    推荐文章