【问题标题】:Passing special character [char(11), char(7)] in stored procedure as string将存储过程中的特殊字符 [char(11), char(7)] 作为字符串传递
【发布时间】:2018-12-21 09:47:42
【问题描述】:

我想在表格中搜索所有带有特殊字符的记录 - char(11)、char(7) 等。

我找到了一个可以帮助我找到它的存储过程。但它不接受输入参数如下:

EXEC sp_FindStringInTable '%'+char(7)+'%', 'CPOA-TALENTLink-Test-Leeds', 'TALENT_Contact_ChangeLog'

错误

消息 102,第 15 级,状态 1,第 1 行
'+' 附近的语法不正确。

存储过程:

CREATE PROCEDURE dbo.sp_FindStringInTable 
     @stringToFind NVARCHAR(100), 
     @schema SYSNAME, 
     @table SYSNAME
AS
BEGIN TRY
    DECLARE @sqlCommand VARCHAR(MAX) = 'SELECT * FROM [' + @schema + '].[' + @table + '] WHERE ' 

    SELECT @sqlCommand = @sqlCommand + '[' + COLUMN_NAME + '] LIKE ''' + @stringToFind + ''' OR '
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_SCHEMA = @schema
      AND TABLE_NAME = @table 
      AND DATA_TYPE IN ('char','nchar','ntext','nvarchar','text','varchar')

    SET @sqlCommand = LEFT(@sqlCommand, LEN(@sqlCommand) - 3)

    EXEC (@sqlCommand)
   PRINT @sqlCommand
END TRY
BEGIN CATCH 
   PRINT 'There was an error. Check to make sure object exists.'
   PRINT error_message()
END CATCH 

如错误所述,我无法在表格中搜索特殊字符。

【问题讨论】:

标签: sql sql-server stored-procedures special-characters


【解决方案1】:

在调用过程中,除文字或变量之外的表达式不起作用。

将串联分配给一个变量并将该变量传递给过程。

DECLARE @p varchar(max) = '%' + char(7) + '%';

EXEC sp_FindStringInTable @p, 'CPOA-TALENTLink-Test-Leeds', 'TALENT_Contact_ChangeLog';

【讨论】:

  • 这并没有解决你的 SQL 中的巨大注入漏洞,@PratikSoni。你真的需要修复它。
  • 例如,有人可能会传递EXEC sp_FindStringInTable '', 'YourTable]; CREATE LOGIN NewSA WITH PASSWORD = ''abc123'', CHECK_POLICY = OFF, CHECK_EXPIRATION = OFF;/*','*/ALTER SERVER ROLE sysadmin ADD MEMBER NewSA;--'; 之类的内容,而您的服务器上很可能有一个全新的 SA。
【解决方案2】:

'[' + @schema + ']'' LIKE ''' + @stringToFind + '''' 这样的文字字符串连接是不安全的。 远非如此。我怀疑对您的查询进行参数化可以解决此问题:

CREATE PROCEDURE dbo.sp_FindStringInTable @stringToFind NVARCHAR(100), @schema sysname, @table sysname 
AS

    BEGIN TRY
        DECLARE @sqlCommand varchar(max);
        SET @sqlCommand = N'SELECT *' + NCHAR(10) + --Formatting yoru dynamic SQL is a very good idea
                          N'FROM ' + QUOTENAME(@schema) + N'.' + QUOTENAME(@table) + NCHAR(10) +
                          N'WHERE' +
                          STUFF((SELECT NCHAR(10) + N'  AND ' + QUOTENAME(COLUMN_NAME) + N'LIKE @String'
                                 FROM INFORMATION_SCHEMA.COLUMNS 
                                 WHERE TABLE_SCHEMA = @schema
                                   AND TABLE_NAME = @table 
                                   AND DATA_TYPE IN ('char','nchar','ntext','nvarchar','text','varchar')
                                 FOR XML PATH(N'')),1,6,N'')
        PRINT @sqlCommand; --your best friend
        EXEC sp_executesql @sqlCommand, N'String nvarchar(100)', @String = @stringToFind;

        END TRY

    BEGIN CATCH 
       PRINT 'There was an error. Check to make sure object exists.'
       PRINT error_message()
    END CATCH 

请注意,我没有测试过上述内容。你最好的朋友会帮你调试。

【讨论】:

    猜你喜欢
    • 2014-02-03
    • 1970-01-01
    • 2011-01-21
    • 2018-07-04
    • 1970-01-01
    • 1970-01-01
    • 2020-09-12
    • 1970-01-01
    • 2014-09-07
    相关资源
    最近更新 更多