我需要查询多个包含列名称'idClient'的特定条件的表。
到目前为止,我已经使用以下查询获取了需要查询的表:
SELECT c.name AS 'ColumnName',
t.name AS 'TableName'
FROM sys.columns c (nolock)
JOIN sys.tables t (nolock) ON c.object_id = t.object_id
WHERE c.name LIKE '%idClient%'
ORDER BY TableName,
ColumnName;
这给了我以下结果(实际上大约返回了100张表):
+------------+-----------------+
| ColumnName | TableName |
+------------+-----------------+
| idClient | tbClient |
| idClient | tbClientContact |
| idClient | tbInvoice |
+------------+-----------------+
为了让我在每个表中都能找到所有的客户记录,我目前正在为每个表名运行3个单独的查询。例如:
SELECT * FROM tbClientContact (nolock)
JOIN tbClient (nolock)
ON tbClientContact.idClient = tbClient.idClient
WHERE tbClient.vcSurname = 'Smith'
代替对每个表运行上述查询3次,有没有更简单的方法对作为TableName返回的所有结果运行相同的查询?
目标:在上述示例中,我的任务是从客户姓氏为“ Smith”的数据库中删除所有客户记录。我正在运行上面的SELECT查询,以查找所有姓为“ Smith”的客户机的idClient是否将孤儿记录留在表中有“ idClient”链接的表中。我正在加入tbClient,因为除了tbClient之外,其他任何表中都不存在vcSurname列。
答案 0 :(得分:3)
您可以尝试
SELECT idClient FROM tbClient WHERE vcSurname = 'Smith'
UNION ALL
SELECT idClient FROM tbClientContact WHERE vcSurname = 'Smith'
UNION ALL
SELECT idClient FROM tbInvoice WHERE vcSurname = 'Smith'
如果您需要更多的列输出,则所有三个查询必须具有相同数量的输出列并且所有类型都相同
修改 正如其他人所建议的那样,知道您在做什么将很有帮助,因为您尝试的方法绝不是做某事的最佳方法。但是,下面的游标解决方案应构建一个动态查询以执行您想要的
DECLARE @table AS NVARCHAR(128)
DECLARE @sql AS NVARCHAR(4000)
DECLARE c CURSOR FOR
-- hey all the tables with the columns LIKE '%idClient%'
SELECT t.name AS 'TableName'
FROM sys.columns c (nolock)
JOIN sys.tables t (nolock) ON c.object_id = t.object_id
WHERE c.name LIKE '%idClient%'
ORDER BY TableName
-- loop through the results of the query line by line
OPEN c
FETCH NEXT FROM c INTO @table
WHILE @@FETCH_STATUS = 0
BEGIN
-- build the query dynamically
SET @sql =CONCAT(@sql,'SELECT idClient FROM ' + @table + ' WHERE vcSurname = ''Smith'' UNION ALL ')
FETCH NEXT FROM c INTO @table
END
-- remove last "UNION ALL" text
SET @sql = STUFF(@sql,LEN(@sql)-9,11,'')
EXEC sp_executesql @stmt = @sql
CLOSE c
DEALLOCATE c
编辑编辑
刚刚看到了您的修改。您的表是否具有外键/主键对,外键是否具有ON DELETE CASCADE
?如果是这样,应该只是
DELETE from tbClient WHERE vcSurname = 'Smith'
答案 1 :(得分:2)
对于自动查询:
提问后修改:
SELECT 'SELECT '+c.name+' FROM '+t.name+' T WITH(nolock)
JOIN tbClient (NOLOCK)
ON T.idClient = tbClient.idClient
WHERE vcSurname = ''Smith''
UNION ALL
'
FROM sys.columns c (nolock)
JOIN sys.tables t (nolock) ON c.object_id = t.object_id
WHERE c.name LIKE '%idClient%'
以文本格式(ctrl + T)打印结果。
复制完整的结果,然后删除最后一个UNION ALL
答案 2 :(得分:1)
1通过查询systable(sysforeignkeys
或syscolumns
(如果您没有FK)来确定涉及的表。
2手动编写一个用于完成所有操作的全面存储过程
create proc dbo.Client_Del
@client_id int
as
begin try
if not exists(select 1 from dbo.Client c where c.id = @client_id)
raiserror("Client %d not found", 16, 1, @client_id)
begin tran
delete ct
from dbo.ClientContacts ct
where ct.client_id = @client_id
delete idt
from dbo.InvoiceDetail idt
inner join dbo.Invoice i
on i.invoice_id = idt.invoice_id
where i.client_id = @client_id
delete i
from dbo.Invoice i
where i.client_id = @client_id
delete c
from dbo.Client c
where c.client_id = @client_id
commit tran
end try
begin catch
if @@trancount > 0
rollback tran
throw
end catch
GO
3使用参数调用存储的proc
declare @id int
set @id = (select c.client_id from dbo.Client c where c.LastName = 'Smith')
exec dbo.Client_Del
@client_id = @id
答案 3 :(得分:0)
我不确定您需要什么。这篇文章是
@Luv
的增强代码。使用它,您只需运行它即可。
declare @select nvarchar(max) = N''
set @select =
N'
declare @sql nvarchar(max) = N''''
SELECT @sql += '' UNION ALL SELECT ''+c.name+'' FROM ''+t.name+'' T WITH(nolock)
JOIN tbClient (NOLOCK)
ON T.idClient = tbClient.idClient
WHERE vcSurname = ''''Smith''''''
FROM sys.columns c (nolock)
JOIN sys.tables t (nolock) ON c.object_id = t.object_id
WHERE c.name LIKE ''%yourColumnName%''
set @sql = STUFF(@sql, 1, 10, '''')
print @sql
exec sp_executesql @sql
'
exec sp_executesql @select