我創建了一個存儲過程你。
此過程檢查MSSQL元構建返回包含列名N
和它們的值V
結果的動態SQL字符串,相應的行鍵K
從其中該值被檢索,用於指定表。
執行此操作時,結果存儲在名爲## ColumnsByValue的全局臨時表中,然後可以直接查詢該表。
創建GetColumnsByValue
存儲過程中,通過執行該腳本:
-- =============================================
-- Author: Ben Roberts ([email protected])
-- Create date: 22 Mar 2013
-- Description: Returns the names of columns that contain the specified value, for a given row
-- =============================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF OBJECT_ID ('dbo.GetColumnsByValue', 'P') IS NOT NULL
DROP PROCEDURE dbo.GetColumnsByValue;
GO
CREATE PROCEDURE dbo.GetColumnsByValue
-- Add the parameters for the stored procedure here
@idColumn sysname,
@valueToFind nvarchar(255),
@dbName sysname,
@tableName sysname,
@schemaName sysname,
@debugMode int = 0
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @SQL nvarchar(max);
DECLARE @SQLUnion nvarchar(max);
DECLARE @colName sysname;
DECLARE @dbContext nvarchar(256);
DECLARE @Union nvarchar(10);
SELECT @dbContext = @dbName + '.' + @schemaName + '.sp_executeSQL';
SELECT @SQLUnion = '';
SELECT @Union = '';
IF OBJECT_ID ('tempdb..##GetColumnsByValueIgnoreList') IS NULL -- no columns to ingore have been specified, need to create an empty list.
BEGIN
CREATE TABLE ##GetColumnsByValueIgnoreList (column_name nvarchar(255));
END
DECLARE DBcursor CURSOR FOR
SELECT
COLUMN_NAME
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = @tableName
AND
TABLE_SCHEMA = @schemaName;
OPEN DBcursor;
FETCH DBcursor INTO @colName;
WHILE (@@FETCH_STATUS = 0)
BEGIN
IF (
@colName != @idColumn
AND
@colName NOT IN (SELECT column_name FROM ##GetColumnsByValueIgnoreList)
)
BEGIN
SELECT @SQL = 'SELECT '[email protected]+' as K, '''[email protected]+''' as N, ' [email protected]+ ' as V FROM ' + @dbName + '.' + @schemaName + '.' + @tableName;
--PRINT @SQL;
SELECT @SQLUnion = @SQL + @Union + @SQLUnion;
SELECT @Union = ' UNION ';
END
FETCH DBcursor INTO @colName;
END; -- while
CLOSE DBcursor; DEALLOCATE DBcursor;
IF (@debugMode != 0)
BEGIN
PRINT @SQLUnion;
PRINT @dbContext;
END
ELSE
BEGIN
-- Delete the temp table if it has already been created.
IF OBJECT_ID ('tempdb..##ColumnsByValue') IS NOT NULL
BEGIN
DROP TABLE ##ColumnsByValue
END
-- Create a new temp table
CREATE TABLE ##ColumnsByValue (
K nvarchar(255), -- Key
N nvarchar(255), -- Column Name
V nvarchar(255) -- Column Value
)
-- Populate it with the results from our dynamically generated SQL.
INSERT INTO ##ColumnsByValue EXEC @dbContext @SQLUnion;
END
END
GO
的SP需要幾個輸入作爲參數,這些在下面的代碼說明。
還請注意我提供了一個機制,增加一個「忽略列表」作爲輸入:
- 這可以讓你列出不應該被包括在結果 任何列名。
- 您不需要添加您用作鍵的列,即您的示例結構中的
row_id
。
- 您必須包含其他不是
varchar
的列作爲 這些會導致錯誤(因爲SP只是在它看到的所有列上執行varchar
比較 )。
- 這是通過你必須創建/填充
- 你的示例表結構表明 表中包含的興趣只列一個臨時表完成的,所以這可能並不適用於 你。
,我們提供瞭如何做到這一點(但只有這樣做,如果你需要向)示例代碼:
IF OBJECT_ID ('tempdb..##GetColumnsByValueIgnoreList') IS NOT NULL
BEGIN
DROP TABLE ##GetColumnsByValueIgnoreList;
END
CREATE TABLE ##GetColumnsByValueIgnoreList (column_name nvarchar(255));
INSERT INTO ##GetColumnsByValueIgnoreList VALUES ('a_column');
INSERT INTO ##GetColumnsByValueIgnoreList VALUES ('another_column');
INSERT INTO ##GetColumnsByValueIgnoreList VALUES ('yet_another_column');
現在,斷火是打造您的臨時表的過程結果,請使用以下代碼(當然,也可以根據需要進行修改)。
-- Build the ##ColumnsByValue table
EXEC dbo.GetColumnsByValue
@idColumn = 'row_id', -- The name of the column that contains your row ID (eg probably your PK column)
@dbName = 'your_db_name',
@tableName = 'your_table_name',
@schemaName = 'dbo',
@debugMode = 0 -- Set this to 1 if you just want a print out of the SQL used to build the temp table, to 0 if you want the temp table populated
這給你留下##ColumnsByValue
上,您可以執行任何你需要的搜索,例如:
select * from ##ColumnsByValue WHERE v = 'luxury' and k = 5 --some_row_id
你需要重新執行存儲過程(如果相關,創建/修改它之前的忽略列表表格)爲每個要檢查的表格。
這種方法的一個關注點是nvarchar的長度可能會在您的案件超過。你會問。需要使用不同的數據類型,減少列名的長度等等。或者把它分解成子步驟和聯合在一起的結果讓你以後的結果集。
我的另一個問題是,這是完全矯枉過正,針對您的特定場景,一次性的腳本到查詢窗口將爲您提供所需的基礎,然後在Notepad ++中進行一些巧妙的文本編輯讓你一直在那裏......因此這個問題很可能(並且相當合理)讓你這樣做!但它是一個很好的一般情況下的問題,因此值得有興趣的人將來;-)回答
是的,我已經看到這種情況使用元從系統表,我敢肯定有人比我更會knowleagable根據這些方面提供答案。但同時,請嘗試右鍵單擊表>腳本表爲>創建到>新查詢編輯器窗口?腳本中給出了整個列的列表。根據需要複製並使用這些字段。 (從http://stackoverflow.com/questions/600446/sql-server-how-do-you-return-the-column-names-from-a-table) – Sepster 2013-03-21 03:39:08
由於沒有一個已加強了一個間位基於計算機的答案...我已經添加了一個在我的小測試數據庫下工作的。 – Sepster 2013-03-21 04:29:28