2017-10-09 3 views
1

J'ai une table dans SQL Server et j'ai besoin de trouver la colonne qui a la même valeur (appelez-la 'b67') pour toutes les lignes, mais je ne maintenant le nom de la colonne (parce que le nom de la colonne change très souvent). J'ai besoin de trouver cette colonne et de demander à la colonne suivante l'autre partie de la valeur (les 2 colonnes sont toujours ensemble).Trouver une valeur dans une table SQL Server et obtenir la colonne suivante

Exemple de tableau (imaginez la même chose, mais avec plus '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 
+3

Pourquoi les noms de colonnes changent? On dirait une mauvaise idée. – jarlh

+0

Rechercher les personnes qui contrôlent la base de données, mettre de nouvelles colonnes et tout modifier, par exemple maintenant la colonne 'b67', avoir les choses du 'c45', – KMG104

+0

Comment exactement le nom de colonne suivant est défini? – gotqn

Répondre

0

Il est pas très clair qu'est-ce exactement que vous avez besoin, mais jetez un oeil à cette 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 
0

Vous pouvez créer un SQL dynamique pour tester chaque colonne. Je l'ai utilisé DM_EXEC_DESCRIBE_FIRST_RESULT_SET pour obtenir les noms de colonnes, mais vous pouvez également utiliser SELECT * FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'MYTABLE'

je stocke le numéro colonne, le nom de la colonne et la requête SQL pour tester la colonne dans une température (variable) table et boucle thro même des colonnes pour tester la valeur passée.

Il devrait fonctionner

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 '[email protected],NULL,1) 
    ), 
    S AS (
     SELECT COLUMN_ORDINAL, 'SET @CNT= CASE WHEN EXISTS(SELECT TOP 1 1 FROM '+ @TABLENAME + ' WHERE ISNULL(' + [NAME] + ', '''')<>'''[email protected]+''') 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', @[email protected] OUTPUT 

     IF @C = 1 BEGIN 
      SELECT [NAME] FROM @S WHERE [email protected]+1 
      RETURN 
     END 

     DELETE FROM @S WHERE ID = @ID 
    END 
    SELECT NULL [NAME] 
END 

Sortie

NAME 
c45