我有一个带有列ID的帐户表
从所有@ID
中保存,并保存为查询以供以后使用
(我有数千个帐户)
ID
------------------------------------
8C76EF27-3080-4DAA-881B-08CD2A1A558F
62FFCB40-AAB4-47A5-953A-08CD2A1A6A43
CFFD7C3C-FEFC-4E97-9970-08CD2A1A3A60
0F5ADAF3-32EF-4D43-BFBD-08CD2A1A5D88
4130153C-24C1-4914-A6F1-08CD2A16DF59
我发现类似这样的东西可以生成一个弹性查询来检索列ID 在要执行的sql中
with getAllAccount as(
select B.ID,B.DisplayName from (
select ID,DisplayName from u3_system.[dbo].[Account] with (nolock)
where ID = '8c76ef27-3080-4daa-881b-08cd2a1a555f' or ParentID = '8c76ef27-3080-4daa-881b-08cd2a1a555f') A
join u3_system.[dbo].[Account] B with (nolock)
on A.ID = B.ParentID
union
select ID,DisplayName from u3_system.[dbo].[Account] with (nolock)
where ID = '8c76ef27-3080-4daa-881b-08cd2a1a555f'
)
--create pre script
Select 'if exists (select * from sys.tables where name = ''Maillog_' + replace(getAllAccount.ID,'-','') + ') begin Select CampaignID,mailoutID,deliveryDate from u3_data.data.Maillog_' + replace(getAllAccount.ID,'-','') + ' with(nolock) end union '
from getAllAccount
我想选择所有存在的帐户,然后合并在一起, 并且会有成千上万的帐户,其中一些存在,一些不存在,
现在工会在这种情况下不起作用。 还有另一种方法吗?非常感谢
答案 0 :(得分:1)
不确定“查询供以后使用”是什么意思。您可以使用以下简单查询为所有表生成选择查询-
Select CONCAT('select * from u5_data.data.Mailtable_', ID) from Account
它将生成以下输出,您可以将其保存在文件中以供以后使用。
select * from u5_data.data.Mailtable_8C76EF27-3080-4DAA-881B-08CD2A1A558F
select * from u5_data.data.Mailtable_62FFCB40-AAB4-47A5-953A-08CD2A1A6A43
select * from u5_data.data.Mailtable_CFFD7C3C-FEFC-4E97-9970-08CD2A1A3A60
select * from u5_data.data.Mailtable_0F5ADAF3-32EF-4D43-BFBD-08CD2A1A5D88
select * from u5_data.data.Mailtable_4130153C-24C1-4914-A6F1-08CD2A16DF59
答案 1 :(得分:1)
这很有趣; I just tweeted today是我20年来作为SQL开发人员遇到的最糟糕的数据库设计,这个问题听起来很相似。听起来好像您有一堆表,除了名称相同,而且名称代表您要为其检索数据的实体。您现在正尝试批量处理,因此对于存储在帐户中的每个实体,您都希望为这些帐户拉回(我假设为)单个数据集。
这可以通过几种不同的方式来完成,所有这些方式都令人生厌。如果对该数据库的设计有影响,请尝试找出一种重构它的方法。我为此示例选择了CURSOR路由,但也可以使用视图或单个动态SQL语句来完成。但是,这两个选项仅在表的数量较小时才起作用(我过去使用90个或更少的表来完成)。因为我不知道,所以这里是CURSOR。
USE tempdb;
/*set up demo up here*/
CREATE TABLE Account (ID uniqueidentifier)
INSERT INTO Account (ID)
VALUES ('8C76EF27-3080-4DAA-881B-08CD2A1A558F'),
('62FFCB40-AAB4-47A5-953A-08CD2A1A6A43'),
('CFFD7C3C-FEFC-4E97-9970-08CD2A1A3A60'),
('0F5ADAF3-32EF-4D43-BFBD-08CD2A1A5D88'),
('4130153C-24C1-4914-A6F1-08CD2A16DF59')
--these are not temp tables; be sure to clean up. naming has hyphens
CREATE TABLE [MT_4130153C-24C1-4914-A6F1-08CD2A16DF59] (val varchar(20))
CREATE TABLE [MT_CFFD7C3C-FEFC-4E97-9970-08CD2A1A3A60] (val varchar(20))
CREATE TABLE [MT_8C76EF27-3080-4DAA-881B-08CD2A1A558F] (val varchar(20))
CREATE TABLE [MT_0F5ADAF3-32EF-4D43-BFBD-08CD2A1A5D88] (val varchar(20))
CREATE TABLE [MT_62FFCB40-AAB4-47A5-953A-08CD2A1A6A43] (val varchar(20))
INSERT INTO [MT_4130153C-24C1-4914-A6F1-08CD2A16DF59] VALUES ('This')
INSERT INTO [MT_CFFD7C3C-FEFC-4E97-9970-08CD2A1A3A60] VALUES ('is')
INSERT INTO [MT_8C76EF27-3080-4DAA-881B-08CD2A1A558F] VALUES ('a')
INSERT INTO [MT_0F5ADAF3-32EF-4D43-BFBD-08CD2A1A5D88] VALUES ('bad')
INSERT INTO [MT_62FFCB40-AAB4-47A5-953A-08CD2A1A6A43] VALUES ('design')
/*magic starts here*/
CREATE TABLE #output (val varchar(20), id uniqueidentifier)
DECLARE @sql nvarchar(200), @Id varchar(50)
DECLARE c CURSOR FOR
SELECT CONVERT(VARCHAR(50), ID) FROM account
OPEN C
FETCH NEXT FROM C INTO @ID
WHILE @@FETCH_STATUS = 0
BEGIN
SET @SQL = 'SELECT val, ''' + @ID + ''' FROM [MT_' + @ID + ']'
INSERT INTO #output (val, id)
exec sp_executesql @SQL
FETCH NEXT FROM C INTO @ID
END
CLOSE C
DEALLOCATE C
/*output comes next*/
SELECT *
FROM #output
ORDER BY ID
DROP TABLE #output
/*clean up demo*/
DROP TABLE Account
DROP TABLE [MT_4130153C-24C1-4914-A6F1-08CD2A16DF59]
DROP TABLE [MT_CFFD7C3C-FEFC-4E97-9970-08CD2A1A3A60]
DROP TABLE [MT_8C76EF27-3080-4DAA-881B-08CD2A1A558F]
DROP TABLE [MT_0F5ADAF3-32EF-4D43-BFBD-08CD2A1A5D88]
DROP TABLE [MT_62FFCB40-AAB4-47A5-953A-08CD2A1A6A43]
长话短说,您遍历accounts表中的每个值并编写动态SQL语句。您可以按ID执行该操作,然后将该SQL语句的输出插入临时表中,然后从该临时表中选择结果。
答案 2 :(得分:0)
在脚本下方使用光标
create table tbl(ID varchar(max))
insert into tbl values('8C76EF27-3080-4DAA-881B-08CD2A1A558F')
insert into tbl values('62FFCB40-AAB4-47A5-953A-08CD2A1A6A43')
insert into tbl values('CFFD7C3C-FEFC-4E97-9970-08CD2A1A3A60')
insert into tbl values('0F5ADAF3-32EF-4D43-BFBD-08CD2A1A5D88')
insert into tbl values('4130153C-24C1-4914-A6F1-08CD2A16DF59')
DECLARE @sql varchar(max)
SELECT CONCAT('SELECT * FROM ',[ID], CHAR(13) + CHAR(10) ) as execRecord
into #tmp
from tbl
select * from #tmp
DECLARE ID_Cursor CURSOR FOR
SELECT execRecord from #tmp
DECLARE @tmpID varchar(max)
OPEN ID_Cursor
FETCH NEXT FROM ID_Cursor INTO @tmpID
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql = @tmpID
EXECUTE SP_EXECUTESQL @sql
SET @sql = ''
FETCH NEXT FROM ID_Cursor INTO @tmpID
END
CLOSE ID_Cursor
DEALLOCATE ID_Cursor
DROP TABLE #tmp
DROP TABLE tbl
答案 3 :(得分:0)
您无法在SQL中参数化对象标识符(即,不能为此使用SqlParameter
),而必须使用“动态SQL”-这意味着您必须小心避免SQL注入。
假设您必须完全在T-SQL中完成此操作,那么我强烈建议您使用SQL Server 2017,因为它引入了非常有用 STRING_AGG
函数(相当于MySQL的{{1} }函数)。
像这样:
GROUP_CONCAT
答案 4 :(得分:0)
找到答案
Select * from
( Select case when exists (select * from sys.tables where name = 'Maillog_' + replace(getAllAccount.ID,'-',''))
Then 'Select CampaignID,mailoutID,deliveryDate from u3_data.data.Maillog_' + replace(getAllAccount.ID,'-','') + ' with(nolock) union ' End execQuery
from getAllAccount
) A
where execQuery is not null