【问题标题】:Error in my stored procedure in SQL Server我在 SQL Server 中的存储过程出错
【发布时间】:2019-02-03 01:33:57
【问题描述】:

我尝试编写将检查的存储过程:

  1. 如果表和列存在,那么我们写入数据
  2. 如果表不存在,则创建它并写入数据
  3. 如果表存在,则检查现有列并将数据写入存在 列

这是代码:

CREATE PROCEDURE [dbo].[my_proc] @file_path VARCHAR(1000) = NULL
    ,@file_type VARCHAR(1000) = NULL
    ,@file_name VARCHAR(1000) = NULL
    ,@table_name VARCHAR(1000)
AS
BEGIN
    DECLARE @sql NVARCHAR(4000);

    SET @table_name = '[dbo].[' + @table_name + ']'
    SET @sql = '
    DECLARE @msg VARCHAR(max)

    --if column and table exist
    IF (
            EXISTS (
                SELECT *
                FROM sys.objects
                WHERE object_id = OBJECT_ID(''' + @table_name + ''', ''U'')
                ) --табличка
            AND EXISTS (
                SELECT *
                FROM sys.columns
                WHERE object_id = OBJECT_ID(''' + @table_name + ''', ''U'')
                    AND (
                        NAME = '' path_file ''
                        AND NAME = '' file_type ''
                        AND NAME = '' file_name ''
                        )
                )
            ) --поля
    BEGIN
        INSERT INTO ' + @table_name + ' (
            file_path
            ,file_type
            ,file_name
            )
        VALUES (
            ''' + isnull(@file_path, '') + '''
            ,''' + isnull(@file_type, '') + '''
            ,''' + isnull(@f ile_name, '') + '''
            )
    END

    --if table not exist
    IF NOT EXISTS (
            SELECT *
            FROM sys.objects
            WHERE object_id = OBJECT_ID(''' + @table_name + ''', ''U'')
            )
    BEGIN
        CREATE TABLE ' + @table_name + ' (
            id INT NOT NULL identity(1, 1) PRIMARY KEY
            ,file_path TEXT
            ,file_name TEXT
            ,file_type TEXT
            )
    END

    --if table exist
    IF EXISTS (
            SELECT *
            FROM sys.objects
            WHERE object_id = OBJECT_ID(''' + @table_name + ''', ''U'')
            )
    BEGIN
        --check for columns in table
        --file_path
        IF NOT EXISTS (
                SELECT *
                FROM sys.columns
                WHERE object_id = OBJECT_ID(''' + @table_name + ''', ''U'')
                    AND (
                        NAME = ''path_file''
                        OR NAME = ''file_path''
                        )
                )
        BEGIN
            PRINT (''NOT COLUMN path_file'')
        END

        --file name
        IF NOT EXISTS (
                SELECT *
                FROM sys.columns
                WHERE object_id = OBJECT_ID(''' + @table_name + ''', '' U '')
                    AND NAME = '' file_name ''
                )
        BEGIN
            PRINT ('' NOT COLUMN file_name '')
        END

        --file_type
        IF NOT EXISTS (
                SELECT *
                FROM sys.columns
                WHERE object_id = OBJECT_ID(''' + @table_name + ''', ''U'')
                    AND (
                        NAME = ''file_type''
                        OR NAME = ''file_type''
                        )
                )
        BEGIN
            PRINT (''NOT COLUMN file_type'')
        END
        ELSE
            INSERT INTO ' + @table_name + ' (
                file_path
                ,file_name
                ,file_type
                )
            VALUES (
                ''' + isnull(@file_path, '') + '''
                ,''' + isnull(@file_name, '') + '''
                ,''' + isnull(@f ile_type, '') + '''
                )
    END';

    EXEC (@sql);
END

已经存在的表有问题,但没有我需要的列

请帮帮我

【问题讨论】:

  • 你能发布正在执行的确切查询吗?您可以通过将print @sql 放在最后一行之前来获得它。因此,当您在 SSMS 中执行 SP 时,它将打印查询。另外,请注意您的程序容易受到SQL Injection 的攻击。
  • 首先,解决注入问题。参数化您的 SQL 并引用您的对象名称。也不要将varchar(1000) 用于@table_name。对象名称的定义是nvarchar(128)(或sysname)。使用 1000 会使您过度暴露于注入,尤其是当其中 872 个字符永远无法用于有效的对象名称时。
  • 这是处理数据库中数据插入的一种不同寻常的方式。看起来像 XY 问题 (xyproblem.info)。您能分享一下您要解决的问题吗?

标签: sql sql-server stored-procedures dynamic


【解决方案1】:

我尝试运行您的脚本,唯一的错误是未声明的变量。

您正在用空格写“@file_name”。

顺便说一句,我建议您拆分代码来阅读。我尽量少弄乱。

CREATE PROCEDURE [dbo].[my_proc] 
    @file_path VARCHAR(1000) = NULL
    ,@file_type VARCHAR(1000) = NULL
    ,@file_name VARCHAR(1000) = NULL
    ,@table_name VARCHAR(1000)
AS
BEGIN
    DECLARE @sql NVARCHAR(4000);
    DECLARE @msg VARCHAR(max);

    SET @table_name = '[dbo].[' + @table_name + ']'
    SET @sql = '
    --If table not exist then we create it
    IF NOT EXISTS (
            SELECT *
            FROM sys.objects
            WHERE object_id = OBJECT_ID(N''' + @table_name + ''')
                AND type IN (N''U'')
            )
    BEGIN
        CREATE TABLE ' + @table_name + ' (
            id INT NOT NULL identity(1, 1) PRIMARY KEY
            ,file_path TEXT
            ,file_name TEXT
            ,file_type TEXT
            )
    END';

    EXEC (@sql);

    SET @sql = '
    --If table exist then we check existing columns and we write data into exists columns
    IF EXISTS (
            SELECT *
            FROM sys.objects
            WHERE object_id = OBJECT_ID(''' + @table_name + ''', ''U'')
            )
    BEGIN
        PRINT (''TABLE found'')

        --check for columns in table
        --file_path
        IF NOT EXISTS (
                SELECT *
                FROM sys.columns
                WHERE object_id = OBJECT_ID(''' + @table_name + ''', '' U '')
                    AND (
                        NAME = '' path_file ''
                        OR NAME = ''file_path''
                        )
                )
        BEGIN
            PRINT (''NOT COLUMN path_file'')
        END

        --file name
        IF NOT EXISTS (
                SELECT *
                FROM sys.columns
                WHERE object_id = OBJECT_ID(''' + @table_name + ''', ''U'')
                    AND NAME = ''file_name''
                )
        BEGIN
            PRINT (''NOT COLUMN file_name'')
        END

        --file_type
        IF NOT EXISTS (
                SELECT *
                FROM sys.columns
                WHERE object_id = OBJECT_ID(''' + @table_name + ''', ''U'')
                    AND (
                        NAME = ''file_type''
                        OR NAME = ''file_type''
                        )
                )
        BEGIN
            PRINT (''NOT COLUMN file_type'')
        END
        ELSE
            INSERT INTO ' + @table_name + ' (
                file_path
                ,file_name
                ,file_type
                )
            VALUES (
                ''' + isnull(@file_path, '') + '''
                ,''' + isnull(@file_name, '') + '''
                ,''' + isnull(@file_type, '') + '''
                )
    END';

    EXEC (@sql);

    SET @sql = '
    --If table and columns exists then we write data
    IF (
            EXISTS (
                SELECT *
                FROM sys.objects
                WHERE object_id = OBJECT_ID(''' + @table_name + ''', ''U'')
                ) --табличка
            AND EXISTS (
                SELECT *
                FROM sys.columns
                WHERE object_id = OBJECT_ID(''' + @table_name + ''', ''U'')
                    AND (
                        NAME = ''path_file''
                        AND NAME = ''file_type''
                        AND NAME = ''file_name''
                        )
                )
            ) --поля
    BEGIN
        INSERT INTO ' + @table_name + ' (
            file_path
            ,file_type
            ,file_name
            )
        VALUES (
            ''' + isnull(@file_path, '') + '''
            ,''' + isnull(@file_type, '') + '''
            ,''' + isnull(@file_name, '') + '''
            )
    END';

    EXEC (@sql);
END

【讨论】:

    猜你喜欢
    • 2018-10-03
    • 2016-07-28
    • 1970-01-01
    • 2019-04-20
    • 1970-01-01
    • 2018-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多