我在SQL Server中有一个表,我需要为所有行找到具有相同值的列(称为'b67'),但我现在不知道列名(因为列的名称更改)常常)。我需要找到这个列并向下一列询问值的另一部分(2列总是在一起)。
表的示例(想象相同,但有更多'coso'
):
ID | coso1 | c45 | coso2 | b63 | Coso3 | d28
---+----------+---------+-------------+--------+--------+----
1 | b63 | 1 | d28 | 5 | c45 | 3
2 | b63 | 4 | d28 | 6 | c45 | 5
3 | b63 | 67 | d28 | 1 | c45 | 2
4 | b63 | 34 | d28 | 5 | c45 | 6
5 | b63 | 8 | d28 | 6 | c45 | 9
答案 0 :(得分:0)
目前还不是很清楚你到底需要什么,但看看那个sql:
create table test_columns
(
coso1 char(3),
c45 int,
coso2 char(3),
b63 int
);
insert into test_columns values ('b63', 1, 'd28', 5)
DECLARE @column_id INT,
@name varchar(200),
@query varchar(max),
@next_column varchar(200)
DECLARE @cursor CURSOR
SET @cursor = CURSOR FOR
select name, column_id from sys.columns where object_name(object_id) = 'test_columns' and name like 'coso%'
OPEN @cursor
FETCH NEXT
FROM @cursor INTO @name, @column_id
WHILE @@FETCH_STATUS = 0
BEGIN
SET @query = 'SELECT 1 FROM dbo.test_columns HAVING COUNT(distinct ' + @name + ') = 1';
EXEC (@query);
IF (@@ROWCOUNT = 1)
BEGIN
SELECT @next_column = name FROM sys.columns where object_name(object_id) = 'test_columns' and column_id = @column_id + 1;
SET @query = 'SELECT ' + @next_column + ', ' + @name + ' FROM dbo.test_columns';
EXEC (@query);
END
FETCH NEXT
FROM @cursor INTO @name, @column_id
END
CLOSE @cursor
DEALLOCATE @cursor
答案 1 :(得分:0)
您可以构建动态SQL来测试每一列。
我使用DM_EXEC_DESCRIBE_FIRST_RESULT_SET
来获取列名,但您也可以使用SELECT * FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'MYTABLE'
我存储列号,列名和sql查询以测试temp(变量)表中的列,然后循环甚至列来测试传递的值。
应该有效
CREATE PROCEDURE FIND_VAL (
@ValuetoFind varchar(100)
)
AS
BEGIN
DECLARE @TABLENAME VARCHAR(100) = 'MYTABLE'
DECLARE @S TABLE (ID INT PRIMARY KEY, SQL_CMD VARCHAR(255), [NAME] VARCHAR(32))
DECLARE @SQL_CMD NVARCHAR(255) = ''
DECLARE @ID INT = 0
DECLARE @C INT
;WITH
C AS (
SELECT * FROM SYS.DM_EXEC_DESCRIBE_FIRST_RESULT_SET('SELECT * FROM '+@TABLENAME,NULL,1)
),
S AS (
SELECT COLUMN_ORDINAL, 'SET @CNT= CASE WHEN EXISTS(SELECT TOP 1 1 FROM '+ @TABLENAME + ' WHERE ISNULL(' + [NAME] + ', '''')<>'''+@VALUETOFIND+''') THEN 0 ELSE 1 END' Q, [NAME]
FROM C
)
INSERT INTO @S
SELECT * FROM S
--SELECT * FROM @S
WHILE EXISTS(SELECT TOP 1 1 FROM @S WHERE (ID % 2)=0 ORDER BY ID) BEGIN
SELECT TOP 1 @ID=ID, @SQL_CMD = SQL_CMD FROM @S WHERE (ID % 2)=0 ORDER BY ID
EXEC SP_EXECUTESQL @SQL_CMD, N'@CNT INT OUTPUT', @CNT=@C OUTPUT
IF @C = 1 BEGIN
SELECT [NAME] FROM @S WHERE ID=@ID+1
RETURN
END
DELETE FROM @S WHERE ID = @ID
END
SELECT NULL [NAME]
END
输出
NAME
c45