2

这是我在@Kenneth Fisher 的帮助下创建的一个存储过程,它工作得非常好而且很安全(可以防止大多数 sql 注入风险)

我想以相同的方式插入数据库是否可以对这段代码进行一些修改以便能够使用它来插入数据?

CREATE PROCEDURE [dbo].[SafeSqlSP_SelectGivenTableWithOptionalColFilterVerB] 
    @columnList nvarchar(max) ='*',
    --@tableSchema sysname ='dbo' ,
    @tableName sysname ,
    @ColNameAsFilter1 nvarchar(255) ='',
    @ColNameAsFilter2 nvarchar(255) ='',
    @ColFilter1VAL nvarchar(max)='',
    @ColFilter2VAL nvarchar(max)=''       
    AS

BEGIN
    SET NOCOUNT ON;
    declare @tableSchema sysname ='dbo' ;
    IF ISNULL(@tableSchema,'') = ''
        SET @tableSchema = 'dbo'

    IF ISNULL(@columnList,'') = ''
        SET @columnList = '*'

    SET @tableName = ISNULL(@tableName,'')
    SET @ColNameAsFilter1 = ISNULL(@ColNameAsFilter1,'')
    SET @ColNameAsFilter2 = ISNULL(@ColNameAsFilter2,'')
    SET @ColFilter1VAL = ISNULL(@ColFilter1VAL,'')
    SET @ColFilter2VAL = ISNULL(@ColFilter2VAL,'')

    IF NOT EXISTS (
                    SELECT * 
                    FROM sys.all_objects
                    JOIN sys.schemas
                        ON sys.all_objects.schema_id = sys.schemas.schema_id
                    WHERE sys.all_objects.name = @tableName
                      AND sys.schemas.name = @tableSchema
                      AND [TYPE] IN ('S','U','V')
                    )
        BEGIN
            RAISERROR (N'Table %s.%s does not exist.',
                        16,
                        1,
                        @tableSchema,
                        @tableName)
            RETURN
        END

    IF @columnList LIKE '% FROM %'
        BEGIN
            RAISERROR (N'The column list passed in contains the word "FROM".  This is a SQL Injection risk and not allowed.',
                        16,
                        1)
            RETURN
        END

    IF @columnList LIKE '%;%'
        BEGIN
            RAISERROR (N'The column list passed in contains a semicolon.  This is a SQL Injection risk and not allowed.',
                        16,
                        1)
            RETURN
        END

    IF @ColNameAsFilter1 <> '' AND
        NOT EXISTS (SELECT * 
                    FROM sys.all_columns
                    WHERE object_id = OBJECT_ID(@tableSchema+'.'+@tableName)
                      AND name = @ColNameAsFilter1)
        BEGIN
            RAISERROR (N'Table %s.%s does not have a column %s.',
                        16,
                        1,
                        @tableSchema,
                        @tableName,
                        @ColNameAsFilter1)
            RETURN
        END

    IF @ColNameAsFilter2 <> '' AND
        NOT EXISTS (SELECT * 
                    FROM sys.all_columns
                    WHERE object_id = OBJECT_ID(@tableSchema+'.'+@tableName)
                      AND name = @ColNameAsFilter2)
        BEGIN
            RAISERROR (N'Table %s.%s does not have a column %s.',
                        16,
                        1,
                        @tableSchema,
                        @tableName,
                        @ColNameAsFilter2)
            RETURN
        END 

    DECLARE @sqlCommand nvarchar(max)

    SET @sqlCommand = 'SELECT ' + @columnList + CHAR(13) +
        ' FROM [' + @tableSchema + '].['+ @tableName + ']' + CHAR(13) + 
        ' WHERE 1=1 '

    IF @ColNameAsFilter1 != ''
        SET @sqlCommand = @sqlCommand + CHAR(13) + 
            ' AND ' + QUOTENAME(@ColNameAsFilter1) + ' = @ColFilter1VAL'

    IF @ColNameAsFilter2 != ''
        SET @sqlCommand = @sqlCommand + CHAR(13) + 
            ' AND ' + QUOTENAME(@ColNameAsFilter2) + ' = @ColFilter2VAL'

    EXECUTE sp_executesql @sqlCommand,
            N'@ColFilter1VAL nvarchar(75), @ColFilter2VAL nvarchar(75)', 
            @ColFilter1VAL, @ColFilter2VAL
END
4

1 回答 1

1

首先阅读本文:何时(不)使用动态 SQL 的常见情况

于 2013-07-16T22:09:31.853 回答