5

是否可以将表名作为输入参数传递给存储过程?

例如:

create procedure test
@tablename char(10)
as
begin
select * from @tablename
end
go

我知道这行不通。那么如果我想将表名传递到存储过程中,最好的方法是什么?

非常感谢

4

3 回答 3

11

The safest way to do this is via a view.

Create a view which unions all the tables you may wish to access (and which must all have the same column structure), and prefix the rows with the table name.

CREATE VIEW MultiTable
AS
    SELECT 'table1' AS TableName, * FROM table1
    UNION ALL
    SELECT 'table2' AS TableName, * FROM table2
    UNION ALL
    SELECT 'table3' AS TableName, * FROM table3

Your stored procedure can now filter on the table name:

CREATE PROCEDURE test
    @TableName varchar(100)
AS
    SELECT * FROM MultiTable WHERE TableName = @TableName

This is safer than using dynamic SQL creation and execution.

于 2012-05-24T09:20:01.833 回答
4

您将需要使用动态 SQL,但您需要注意潜在的 sql 注入风险,就像 @tablename 包含一些狡猾的东西一样,您可能会陷入痛苦的世界。

例如

-- basic check to see if a table with this name exists
IF NOT EXISTS(SELECT * FROM sys.tables WHERE name = @tablename)
    RETURN

DECLARE @sql NVARCHAR(100)
SET @sql = 'SELECT * FROM ' + QUOTENAME(@tablename)
EXECUTE(@sql)

你需要非常小心这种方法,确保你没有打开一罐安全蠕虫。

我的另一个担忧是您可能正在尝试制作通用数据访问存储过程,这通常是一个坏主意。显然我不知道你的用例。

于 2012-05-24T09:21:02.117 回答
2
DECLARE @Name VARCHAR(50)
SET @Name='Company'

EXEC('SELECT * from ' + @Name )

使用这种方式从数据库中获取记录。

于 2012-05-24T09:26:35.053 回答