这是我向StackOverflow发表的第一篇文章。多年来,我一直在使用这个神奇的资源来回答数百个SQL和PowerShell问题,但是这个问题让我难以忍受了好几天。
我正在使用SQL Server 2014 SP2,我正在尝试更新DATABASE1,FIELD1,然后是FIELD2,然后是来自其他多个数据库的FIELD3。
FIELD1可能存在于多个其他数据库之一中。 FIELD1可能不存在于所有数据库中 - 这就是我遇到问题的地方。
我有以下(匿名)查询,它似乎正在运行:
EXEC sp_MSforeachdb 'IF ''?'' IN (''DATABASE2'',''DATABASE3'',''DATABASE4'')
BEGIN
UPDATE DATABASE1.PARAMETER
SET B.[VALUE] = A.[FIELD1]
FROM DATABASE1.TABLE1 B
INNER JOIN ?.dbo.[TABLE2] A
ON A.JOINVALUE = B.JOINVALUE
WHERE B.COLUMN2 = ''SOMETHING''
AND COLUMN3= ''PF.T.FIELD1''
END ;'
直到我说到FIELD8,因为它存在于DATABASE1中但不存在于DATABASE2,DATABASE3或DATABASE4中。然后我得到以下错误:
Msg 207, Level 16, State 1, Line 30
Invalid column name 'FIELD8'.
从我的Google和StackOverflow搜索中,我尝试使用(第一次)a:
IF EXISTS (SELECT COLUMN1 FROM Database2.Table2 WHERE Column1='Field8')
EXEC .......
但那是我开始真正挣扎的地方。
希望以上是有道理的。 任何提示或帮助将不胜感激。
N.B。我在Database1中有大约3,000个需要更新的字段。我已经动态地构建了所有的UPDATE语句。
答案 0 :(得分:1)
首先,sp_MSforeachdb
不可靠。如需工作替代方案,请点击此处:Making a more reliable and flexible sp_MSforeachdb - Aaron Bertrand
其次,您可以使用系统视图来检查给定表中是否存在使用sys.columns
的列,如下所示:
if exists (
select 1
from sys.columns c
where c.name = 'pilots_id' /* column name */
and c.object_id = object_id(N'pilots') /* table name */
)
begin
select 'Pilots_Id exists' /* do stuff */
end
rextester演示:http://rextester.com/UUXCB18567
答案 1 :(得分:1)
您可以创建存储过程,它将搜索系统表中的列和表:
ALTER PROCEDURE dbo.check_table_exists
-- Add the parameters for the stored procedure here
@table_name nvarchar(255),
@column_name nvarchar(255)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
DECLARE @SQLString nvarchar(max),
@ParmDefinition nvarchar(500) = N'@table_name nvarchar(255), @column_name nvarchar(255)';
IF OBJECT_ID(N'tempdb..#check_column_exists') is not null DROP TABLE #check_column_exists
CREATE TABLE #check_column_exists (
db nvarchar(500) NULL,
column_exists bit NULL
)
SELECT @SQLString =
(
SELECT N'USE '+QUOTENAME([name]) +'; '+
'INSERT INTO #check_column_exists '+
'SELECT '''+[name]+''' as [db], '+
' COUNT(*) as column_exists ' +
'FROM sys.tables t ' +
'INNER JOIN sys.columns c ' +
' ON t.[object_id] = c.[object_id] ' +
'WHERE t.[name] = @table_name and c.[name] = @column_name; '
FROM sys.databases
WHERE [name] NOT IN (
'msdb',
'model',
'tempdb',
'master'
)
FOR XML PATH('')
) + 'SELECT [db] FROM #check_column_exists WHERE column_exists = 1; DROP TABLE #check_column_exists;'
EXEC sp_executesql @SQLString, @ParmDefinition, @table_name = @table_name, @column_name = @column_name
END
GO
您可以将其更改为仅搜索列并输出数据库和表名称等等。
输出结果为:
db
-----------
DATABASE1
DATABASE4
...
etc
之后,您可以将其写入表并用于动态SQL更新查询:
DECLARE @table_name nvarchar(255) = 'SomeTable',
@column_name nvarchar(255) = 'SomeField'
DECLARE @results TABLE (
db nvarchar(500)
)
INSERT INTO @results
EXEC dbo.check_table_exists @table_name, @column_name
--...Here goes building of dynamic SQL query to update data