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

如何在SQL Server存储过程中将架构名称作为参数传递?

  •  2
  • xzk  · 技术社区  · 6 年前

    正如我到目前为止所看到的,人们建议使用动态SQL。

    例如:

    How to pass schema as parameter to a stored procedure in sql server?

    How to pass schema name as parameter in stored procedure

    然而,动态SQL有SQL注入的风险。因此,我想知道是否还有其他安全的替代方案?

    基本上,我正在创建的这个存储过程将在运行时调用。将有2个可能的模式要传入。表名也将传入。

    如下所示:(它不起作用)

    CREATE PROCEDURE [EFM].[usp_readApexTable] 
        @SCHEMANAME VARCHAR(20) = NULL,
        @TABLENAME VARCHAR(100) = NULL
    AS
    BEGIN 
        SET NOCOUNT ON;
    
        SELECT *  
        FROM [@SCHEMANAME].[@TABLENAME];
    END
    GO
    

    这只是读取操作的一个示例。我的计划是为CRUD创建,它需要4个不同的存储过程。

    2 回复  |  直到 6 年前
        1
  •  1
  •   marc_s    6 年前

    您可以使用 QUOTENAME 要避免任何SQL注入并构建动态查询,请执行以下操作:

    CREATE PROCEDURE [EFM].[usp_readApexTable] 
        @SCHEMANAME VARCHAR(20) = NULL,
        @TABLENAME VARCHAR(100) = NULL
    AS
    BEGIN 
        SET NOCOUNT ON;
    
        DECLARE @SQL VARCHAR(MAX)=N'SELECT *  FROM '
              + QUOTENAME(@SCHEMANAME) + '.' + QUOTENAME(@TABLENAME)
        EXEC (@SQL)
    END
    GO
    

    注: 如果您计划为您的 WHERE 条款,在这种情况下 引号名称 不会有多大帮助,我建议使用 sp_executesql 通过传递中使用的适当参数 哪里 条款

    仍然需要使用 引号名称 架构和表名为 SQL 除了作为文字外,不能对表和模式使用变量名。

    例如

      declare @sql nvarchar(max)
      set @sql = N'select * from ' + quotename(@SCHEMANAME ) + '.' +  quotename(@TABLENAME ) 
             + '  where (City = @City)' 
      exec sp_executesql 
        @sql, 
        N'@City nvarchar(50)',       
        @City 
    

    您可以找到更多详细信息 here

        2
  •  0
  •   sebu    6 年前

    您需要使用 dynamic sql 要执行此操作

    CREATE PROCEDURE [EFM].[usp_readApexTable] 
    @SCHEMANAME VARCHAR(20) = NULL,
    @TABLENAME VARCHAR(100) = NULL
    AS
    BEGIN 
        SET NOCOUNT ON;
        DECLARE @sqlCommand nvarchar(MAX)
        SET @sqlCommand='SELECT *  FROM ['+@SCHEMANAME+'].['+@TABLENAME+'];'
        --Create Your Temp Table where you can set the records after executing the dynamic query
        CREATE TABLE #tmpTbl(
            Column1 [datatype]
            Column2 [datatype]
            .
            .
            ColumnN
        )
        INSERT INTO #tmpTbl EXEC sp_executesql  @sqlCommand --Copy data to #tmpTbl table
        SELECT * FROM #tmpTbl
        DROP TABLE #tmpTbl
    END
    GO