sql server存储过程如何动态生成表名

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql server存储过程如何动态生成表名相关的知识,希望对你有一定的参考价值。

在存储过程中,用到的表名需要动态生成如:
SET @TABLENAME='DSSXX.DBO.T_ZRXX'+ RIGHT(LEFT(@StartDate,4),2)
形成一个表名字符串;但是这样写的话查询就会报错

select * from @TABLENAME 无法识别的表变量,请教如何生成表名变量

--楼主
--表变量的基本用法

--有一种常规的用法 就是声明表变量 输出表变量里面的数据 这里不管表变量的表是什么

--例子如下

declare @tt table(id int)

insert into @tt

values(1)

select * from @tt

go

--但有的时候 可能会有需要 要输出表名 或自定义表名 那么这个时候要声明字符串 而不是表变量

--方法如下

declare @tt varchar(12)

set @tt=convert(char(10),getdate(),120)

print ('select * from '+@tt)

print @tt

--exec ('select * from '+@tt)追问

之前写成过动态的,但是写成动态之后对变量赋值不好用

追答

你的需求是我个你的第二个方法

参考技术A 查询要写成动态语句。
exec ( ' select * from ' + @TABLENAME )追问

之前写成过动态的,但是写成动态之后对变量赋值不好用

追答

对变量赋值不好用中什么意思?

本回答被提问者采纳
参考技术B 参考如下:
游标处理
BEGIN
DECLARE @Sql varchar(200);
DECLARE @name varchar(10);
SET @Sql='DECLARE cur CURSOR for select [name] from test_dysql';
EXEC(@Sql).
OPEN cur;
FETCH next FROM cur INTO @name;
WHILE @@FETCH_STATUS=0
BEGIN
PRINT @name;
FETCH next FROM cur INTO @name;
END
CLOSE cur;
DEALLOCATE cur;
END.

带参数
BEGIN
DECLARE @Sql NVARCHAR(200);
DECLARE @id INT;
DECLARE @name VARCHAR(10);
SET @id = 1;
SET @name = 'C';
SET @Sql = 'SELECT * FROM test_dysql WHERE id=@id OR name=@name';
PRINT @Sql;
EXEC SP_EXECUTESQL @Sql, N'@id INT, @name VARCHAR(10)', @id, @name;
END.

赋值
BEGIN
DECLARE @Sql NVARCHAR(200);
DECLARE @name VARCHAR(10);
SET @Sql = 'SELECT @name = name FROM test_dysql WHERE id=1';
PRINT @Sql;
EXEC SP_EXECUTESQL @Sql, N'@name VARCHAR(10) OUTPUT', @name OUTPUT;
PRINT @name;
END.

存储过程的 PL/SQL 动态表名

【中文标题】存储过程的 PL/SQL 动态表名【英文标题】:PL/SQL dynamic tablename for stored procedure 【发布时间】:2015-01-13 12:14:43 【问题描述】:

我已经开始学习 PL SQL 存储过程,我有 2 个有趣的问题要问。 在下面的示例中,我 execute employer_details 如果找到,它会返回员工的 ID 和姓名。一切正常,但此过程不是动态的,而是特定于表的

CREATE OR REPLACE PROCEDURE employer_details 
IS 
CURSOR table_cur IS
SELECT id, name FROM employee where id in(12,23,34); -- point 1
table_rec table_cur%rowtype;
BEGIN
OPEN table_cur;
LOOP 
fetch table_cur into table_rec;
EXIT WHEN table_cur%notfound;
dbms_output.put_line(employee.id || ' ' ||employee.name); -- point 2
END LOOP;
END;
/

第一个问题:我们可以通过以下签名使其动态化

CREATE OR REPLACE PROCEDURE employer_details (tablename IN VARCHAR, ID in INTEGER, target IN INTEGER)

在程序中换行

SELECT * FROM tablename where tablename.ID > target  ; (point 1)

我试过了,但出现“表或视图不存在”错误(我正在使用 Oracle/Toad)

第二个问题:我们能否将所有列都视为输出,

dbms_output.put_line(employee.id || ' ' ||employee.name); (point 2)

不仅是 2 列,而且是所有列 (*)

【问题讨论】:

target IN INTEGER 参数是什么??是的,您的所有要求都是可能的。 您可以传递一个表名并使用动态 SQL 来查询它,但您真的需要/想要这样做吗?如果表的结构不同,那么可以输出这样的列值,但不是微不足道的(需要dbms_sql),并且您不应该依赖dbms_output 无论如何都可以显示任何位置。我不确定为什么这会比简单的 SQL 选择更好。也许您可以退后一步,说明您在这里真正需要实现的目标? 那么请指导我,taget id 是,返回大于此特定 id 的行。它的北方特色 那么只使用一个参数target IN INTEGER 我的意思是让我澄清一件事,您是否希望从所有 id 大于传递 id 的员工中退出?? @smn_onrocks 是的,我想显示 > id 的所有列(选择 *) 【参考方案1】:
create table my_poc
(id INTEGER,
name VARCHAR2(60),
 sal  number);

insert into my_poc values (1,'abc',1000);
insert into my_poc values (2,'abc',2000);
insert into my_poc values (3,'abc',3000);
insert into my_poc values (4,'abc',4000);
insert into my_poc values (5,'abc',5000);
insert into my_poc values (6,'abc',6000);



CREATE OR REPLACE PROCEDURE employer_details (p_id INTEGER,filter VARCHAR2,table_name varchar2, out_param out SYS_REFCURSOR)
IS
BEGIN
OPEN out_param for 'select * from '||table_name||' where '||filter||' > '||p_id;
END;

我想这就是你想要的。

【讨论】:

这是一个输出参数SYS_REFCURSOR,它将保存您的输出结果集,您可以在table_name 变量中传递nay 表名,因此您的输出罐将填充到out_param变量 对此很抱歉,但请告诉我该写什么???执行employer_details(3000,'id','my_poc',?????) declare my_cur SYS_REFCURSOR; begin -- Call the procedure employer_details(2,'id','my_poc',my_cur); end; @abidkhan303 - 或with a bind variable, like this。 你可以查看这个link或者这个one【参考方案2】:
    是的,我们可以。查看 OPEN FOR 子句。 是的,我们可以。查看 DBMS_SQL 包。 不,我们不应该在没有充分理由的情况下这样做。通常这是不好的做法。

【讨论】:

以上是关于sql server存储过程如何动态生成表名的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 存储过程参数 - 不同类型

SQL Server生成数据库的数据字典存储过程

SQL SERVER如何查看一个表被哪些存储过程用到?用哪个系统存储过程?

存储过程的 PL/SQL 动态表名

如何自动导出 SQL Server 2008 版本的存储过程

在 SQL Server 存储过程中查找表名的列名作为保留关键字