Помимо упомянутых ответов ... Я хотел бы добавить некоторые другие моменты.
Bias действует как наш якорь. Это путь для нас, чтобы иметь какую-то базовую линию, где мы не опускаемся ниже этого. В терминах графика, например, y = mx + b, он похож на y-перехват этой функции.
output = вводит время весового значения и добавляет значение смещения а затем применить функцию активации.
Вы можете отложить EXEC до завершения цикла курсора. Затем просто отследите имя таблицы внутри цикла и, если оно совпадает, добавьте ИЛИ, в противном случае завершите свой SELECT и начните новый.
DECLARE @lasttable varchar(255);
SET @lasttable='';
FETCH NEXT FROM abc INTO @tableName, @columnName;
WHILE (@@FETCH_STATUS = 0)
BEGIN
IF(@lasttable=@tablename) BEGIN
SET @szQuery = @szQuery + ' OR [' + @columnName + ']=''' + CAST(@searchValue AS varchar(50)) + '''';
END ELSE BEGIN
SET @lasttable = @tablename;
SET @szQuery = @szQuery +
'SELECT '''+@tableName+''' AS TheTable, '''+@columnName+''' AS TheColumn '+
'FROM '+@tableName+' '+
'WHERE '+@columnName+' = '''+CAST(@searchValue AS varchar(50))+''''
END
FETCH NEXT FROM abc INTO @tableName, @columnName;
END
PRINT @szQuery;
EXEC (@szQuery);
Вы также можете создать хранимую процедуру для построения VIEW, который выполняет UNION ALL из всех таблиц и полей uniqueidentifier. Что-то со схемой, подобной этой:
CREATE VIEW all_uuids AS (
SELECT 'prices' AS tablename, 'BookGUID' as fieldname, ID as primarykey, BookGUID AS guid FROM prices
UNION ALL SELECT 'prices', 'AuthorGUID', ID, AuthorGUID FROM prices
UNION ALL SELECT 'othertable', 'otherfield', ID, otherfield FROM othertable
)
Затем вам просто нужно выполнить один оператор SELECT для этого повторно используемого VIEW, чтобы получить все совпадающие GUID. Для поиска в одной таблице используйте коррелированный подзапрос, например :
SELECT * FROM prices WHERE EXISTS (SELECT null FROM all_uuids u WHERE u.primarykey=prices.id AND u.guid=@searchfor AND u.tablename='prices')
, который будет искать по всем полям GUID в таблице цен. SQL Server достаточно умен, чтобы не просматривать другие таблицы, и использует индексы существующих таблиц.
Повторно используя единственное представление, вы можете переходить к циклу по information_schema только при изменении схемы, а не при каждом запросе, и результаты представления можно объединить с большей готовностью, чем результаты хранимой процедуры.
Ответ
Окончательное решение оригинальных постеров, основанное на этом ответе:
CREATE PROCEDURE dbo.FindGUID @searchValue uniqueidentifier AS
/*
Search all tables in the database for a guid
Revision History
6/9/2009: Initally created
6/10/2009: Build or clause of multiple columns on one table
*/
--DECLARE @searchValue uniqueidentifier
--SET @searchValue = '{2A6814B9-8261-452D-A144-13264433864E}'
DECLARE abc CURSOR FOR
SELECT
c.TABLE_SCHEMA, c.TABLE_NAME, c.COLUMN_NAME
FROM INFORMATION_SCHEMA.Columns c
INNER JOIN INFORMATION_SCHEMA.Tables t
ON c.TABLE_NAME = t.TABLE_NAME
AND t.TABLE_TYPE = 'BASE TABLE'
WHERE DATA_TYPE = 'uniqueidentifier'
DECLARE @tableSchema varchar(200)
DECLARE @tableName varchar(200)
DECLARE @columnName varchar(200)
DECLARE @szQuery varchar(8000)
SET @szQuery = ''
DECLARE @lasttable varchar(255);
SET @lasttable='';
OPEN ABC
FETCH NEXT FROM abc INTO @tableSchema, @tableName, @columnName;
WHILE (@@FETCH_STATUS = 0)
BEGIN
IF(@lasttable=@tablename)
BEGIN
SET @szQuery = @szQuery + ' OR [' + @columnName + ']=''' + CAST(@searchValue AS varchar(50)) + '''';
END
ELSE
BEGIN
SET @lasttable = @tablename;
IF @szQuery <> ''
BEGIN
PRINT @szQuery
EXEC ('IF EXISTS (' + @szQuery + ') BEGIN ' + @szQuery + ' END');
END
SET @szQuery =
'SELECT '''+@tableSchema+'.'+@tableName+''' AS TheTable, '''+@columnName+''' AS TheColumn '+
'FROM '+@tableName+' '+
'WHERE '+@columnName+' = '''+CAST(@searchValue AS varchar(50))+''''
END
FETCH NEXT FROM abc INTO @tableSchema, @tableName, @columnName;
END
CLOSE abc
DEALLOCATE abc
IF @szQuery <> ''
BEGIN
PRINT @szQuery
EXEC ('IF EXISTS (' + @szQuery + ') BEGIN ' + @szQuery + ' END');
END
GO
Вот решение для SQL 2000 с безвозмездным использованием курсоров:
declare @searchvalue uniqueidentifier
set @searchValue = '{2A6814B9-8261-452D-A144-13264433864E}'
if object_id('tempdb..#results') is not null drop table #results
create table #results (TableSchema sysname, TableName sysname)
declare @sql nvarchar(4000)
declare @cursor1 cursor
declare @tablename sysname
declare @tableschema sysname
declare @cursor2 cursor
declare @columnname sysname
declare @searchFields nvarchar(4000)
set @cursor1 = cursor for
select t.TABLE_SCHEMA, t.TABLE_NAME
from INFORMATION_SCHEMA.Tables t
where t.TABLE_TYPE = 'BASE TABLE'
and exists (
select * from INFORMATION_SCHEMA.Columns c
where c.TABLE_NAME = t.TABLE_NAME
and c.TABLE_SCHEMA = t.TABLE_SCHEMA
and c.DATA_TYPE = 'uniqueidentifier'
)
open @cursor1
while 1=1 begin
fetch next from @cursor1 into @tableschema, @tablename
if @@fetch_status <> 0 break
set @searchFields = ''
set @cursor2 = cursor for
select c.COLUMN_NAME
from INFORMATION_SCHEMA.Columns c
where c.TABLE_NAME = @tablename
and c.TABLE_SCHEMA = @tableschema
and c.DATA_TYPE = 'uniqueidentifier'
open @cursor2
while 1=1 begin
fetch next from @cursor2 into @columnname
if @@fetch_status <> 0 break
set @searchFields = @searchFields + ', ' + quotename(@columnname)
end
set @searchFields = substring(@searchFields,3,len(@searchFields))
set @sql = ' insert #results'
+ ' select '''+@tableschema+''','''+@tablename+''''
+ ' from '+quotename(@tableschema)+'.'+quotename(@tablename)
+ ' where @searchValue in ('+@searchFields+')'
print @sql
exec sp_executesql @sql, N'@searchValue uniqueidentifier', @searchValue
end
select * from #results
Вот решение для SQL 2005, основанное на решении Ремуса, с временными таблицами для лучшего масштабирования:
DECLARE @searchValue uniqueidentifier
SET @searchValue = '{2A6814B9-8261-452D-A144-13264433864E}'
IF OBJECT_ID('tempdb..#results') IS NOT NULL DROP TABLE #results
CREATE TABLE #results (TableSchema SYSNAME, TableName SYSNAME);
DECLARE @sql NVARCHAR(MAX);
WITH cte_all_tables(SQL) AS (
SELECT
N' INSERT #results (TableSchema, TableName)'
+ N' SELECT ''' + t.TABLE_SCHEMA + ''', ''' + t.TABLE_NAME + N''''
+ N' FROM ' + QUOTENAME(t.TABLE_SCHEMA) + '.' +QUOTENAME(t.TABLE_NAME)
+ N' WHERE ' +
(
SELECT QUOTENAME(c.COLUMN_NAME) + N' = @searchValue OR '
FROM INFORMATION_SCHEMA.Columns c
WHERE c.TABLE_NAME = t.TABLE_NAME
AND c.TABLE_SCHEMA = t.TABLE_SCHEMA
AND c.DATA_TYPE = 'uniqueidentifier'
FOR XML PATH('')
) + N'0=1'
FROM INFORMATION_SCHEMA.Columns c
INNER JOIN INFORMATION_SCHEMA.Tables t
ON c.TABLE_NAME = t.TABLE_NAME
AND t.TABLE_SCHEMA = c.TABLE_SCHEMA
AND t.TABLE_TYPE = 'BASE TABLE'
WHERE DATA_TYPE = 'uniqueidentifier')
SELECT @sql = (SELECT [SQL]+nchar(10) FROM cte_all_tables FOR XML PATH(''));
PRINT @SQL;
exec sp_executesql @sql, N'@searchValue uniqueidentifier', @searchValue;
SELECT * FROM #results
Похоже, что здесь происходит немного больше инженерии ... Вы сказали, что вам просто нужно "найти каких-то конкретных гидов". Возможно, будет проще экспортировать всю базу данных, а затем открыть ее в notepad ++ и найти нужные руководства. Тогда вы увидите всю строку данных в то время и т. Д.
Вы можете прочитать о мастере публикации SQL Server, который экспортирует базу данных в текстовый файл здесь.
Вы можете обернуть все в один SELECT и искать по всем таблицам сразу:
ALTER PROCEDURE dbo.FindGUID @searchValue uniqueidentifier AS
BEGIN
SET NOCOUNT ON;
DECLARE @sql NVARCHAR(MAX);
WITH cte_all_tables(SQL) AS (
SELECT N'SELECT ''' + QUOTENAME(t.TABLE_SCHEMA) + '.' +QUOTENAME(t.TABLE_NAME) +
+ N''' FROM ' + QUOTENAME(t.TABLE_SCHEMA) + '.' +QUOTENAME(t.TABLE_NAME)
+ N' WHERE ' +
(
SELECT QUOTENAME(c.COLUMN_NAME) + N'= @searchValue OR '
FROM INFORMATION_SCHEMA.Columns c
WHERE c.TABLE_NAME = t.TABLE_NAME
AND c.TABLE_SCHEMA = t.TABLE_SCHEMA
AND c.DATA_TYPE = 'uniqueidentifier'
FOR XML PATH('')
) + N' 0=1 '
FROM INFORMATION_SCHEMA.Columns c
INNER JOIN INFORMATION_SCHEMA.Tables t
ON c.TABLE_NAME = t.TABLE_NAME
AND t.TABLE_SCHEMA = c.TABLE_SCHEMA
AND t.TABLE_TYPE = 'BASE TABLE'
WHERE DATA_TYPE = 'uniqueidentifier')
SELECT @sql = (SELECT [SQL] + N' UNION ALL ' FROM cte_all_tables
FOR XML PATH('')) + N' SELECT NULL WHERE 0=1';
PRINT @SQL;
exec sp_executesql @sql, N'@searchValue uniqueidentifier', @searchValue;
END
Я использовал терминаторы надгробных камней, такие как 'OR 0 = 1', и даже весь UNION, но это только потому, что Мне лень обрезать окончание построенных составных строк.
Похоже, вы в основном хотите объединить список столбцов в свой динамический sql. В mssql нет первоклассной функции concat, вы можете написать свой собственный CLR udf для этого, но мне это решение не нравится. Проверьте этот вопрос , чтобы узнать о некоторых решениях для mssql concat.