2010-09-24 29 views
0

继续我的主题“http://stackoverflow.com/questions/3767000/invalid-column-name-though-its-there”查询选择具有类似列的表值

我想编写一个查询,选择具有ENTITYID和DataclassId列作为相同的值(跳过过程的空值)

这里的值的表是我的DB的示例

Table_1 
ID Sequence Type Heigh Weight EntityId DataclassId 
0 1   s  1.4  2.5  42-2c-Qi 42-2c-Qi 
1 2   s  2.4  2.5  zh-km-xd zh-km-xd 
2 3   s  3.4  2.5  8n-tr-l7 8n-tr-l7 

Table_2 
ID Data Person EntityId DataclassId 
0 1  Dave  58-zj-4o 41-2c-Q7 
1 2  Sara  99-op-t6 oy-7j-mf 
2 3  Silve 75-qy-47 2d-74-ds 

Table_3 
ID Name Genre EntityId DataclassId 
0 LR  Ac  78-jd-o9 78-jd-o9 
1 OI  Dr  4t-jb-qj 4t-jb-qj 
2 DH  Do  7j-3e-ol 7j-3e-ol 

Table_4 
ID  Name EntityId DataclassId 
NULL NULL  NULL  NULL 
NULL NULL  NULL  NULL 

Table_5 
ID Data Person EntityId DataclassId 
0 1  Dave  58-zj-4o 41-2c-Q7 
1 2  Sara  99-op-t6 oy-7j-mf 
2 3  Silve fg-se-pl 2d-74-ds 

输出应该

Table_1 
Table_3 

编辑

我还使用C#代码遍历数据库的表。但是我还没有得到正确的结果。我需要的是对rootQ变量的正确查询。

public void getRootTables_checkSP() 
    { 
     string connect = "Data Source= EUADEVS06\\SS2008;Initial Catalog=TacOps_4_0_0_4_test;integrated security=SSPI; persist security info=False;Trusted_Connection=Yes"; 
     //Query to Select all Tables that have 
     //EntityId and DataclassId columns in them 
     string query = 
      "SELECT tabs.name " + 
      "FROM sys.tables tabs INNER JOIN sys.columns cols " + 
      "ON tabs.object_id = cols.object_id " + 
      "AND cols.name IN ('EntityId', 'DataclassId')"; 

     int i = 0; 
     int j = 0; //Count for Root Tables 
     SqlDataReader tables_list = null; 
     SqlDataReader rootTables_list = null; 
     SqlConnection conn = new SqlConnection(connect); 
     SqlConnection conn2 = new SqlConnection(connect); 
     try 
     { 
      //Write all table that have EntityId and 
      //DataclassId cols into tables_list 
      conn.Open(); 
      SqlCommand cmd_1 = new SqlCommand(query, conn); 
      tables_list = cmd_1.ExecuteReader(); 

      while (tables_list.Read()) 
      { 
       //Query to select Root Tables 
       //EntityId and DataclassId values are identical in Root Tables 
       //HERE IS WHERE I GOT STUCK AND COULDN'T FIGURE OUT THE CORRECT QUERY 
       string rootQ = 
        "SELECT * " + 
        "FROM " + tables_list[0] + " " + 
        "WHERE EntityId not NULL " + 
        " AND DataclassId not NULL " + 
        " AND EntityId != DataclassId"; 
       try 
       { 
        //Write Root Tables into rootTables_list 
        conn2.Open(); 
        SqlCommand cmd_2 = new SqlCommand(rootQ, conn2); 
        rootTables_list = cmd_2.ExecuteReader(); 

        //Loop through the rootTables_list and print out the values 
        while (rootTables_list.Read()) 
        { 
         string s = rootTables_list[0].ToString(); 
         Console.WriteLine(s); 
         j++; 
        } 
       } 
       catch (Exception ex) 
       { 
        Console.WriteLine("Error: " + ex); 
       } 
       finally 
       { 
        Console.WriteLine(); 
        Console.WriteLine("{0} Root Tables-Count ", j); 
        Console.WriteLine(); 
        conn2.Close(); 
       } 
       i++; 
      } 

     } 
     catch (Exception e) 
     { 
      Console.WriteLine("Error: " + e); 
     } 
     finally 
     { 
      Console.WriteLine(); 
      Console.WriteLine("{0} All Tables-Count ", i); 
      Console.WriteLine(); 
      conn.Close(); 
     } 

    } 
+1

mmm ...在读完您的原始问题后,AdaTheDev提供的答案有什么问题?它和我做的一样,也是通用的。 – 2010-09-24 08:13:29

+0

如果您的意思是tsql查询,它还返回数据库中也不共享类似列值的表。 – Reda 2010-09-24 08:35:34

+0

每当需求变得更加清晰时,我已经更新了原始问题中的答案,并且它只返回共享匹配列值的表。所以我不知道为什么这个副本已经创建。请参阅并尝试我在这个问题上的回应。 – AdaTheDev 2010-09-24 10:57:01

回答

0

使用SQL和代码的组合而不是大规模查询可能最容易。

如果我这样做,我会创建一个发现这将取消其参赛资格表行的查询:如果返回任何行


SELECT * FROM tablx 
WHERE EntityId not NULL 
AND DataclassId not NULL 
AND EntityId != DataclassId; 

,该表已经出来了。

依次在每个表上使用此查询。如果有任何行被返回,这是不好的;丢弃它。如果未返回任何行,请将该名称保存在列表中。

完成后,您将看到所有有效表的列表。

+0

你是对的我正在使用C#代码以及循环遍历表格。我试过你的解决方案,但它没有奏效。我会将我使用的C#代码添加到原始文章 – Reda 2010-09-24 08:26:11

0

使用游标的整个逻辑 - 不会想到任何其他方式直接在数据库中执行它。 为简洁起见,我只是在光标中打印表名。你可能会做任何处理也包括保存在一个表等以备将来使用

DECLARE @tableName nvarchar(500); 
DECLARE @dynamicQuery nvarchar(600); 

DECLARE candidateTables_cursor CURSOR FOR 
SELECT tabs.name 
FROM sys.tables tabs INNER JOIN sys.columns cols 
ON tabs.object_id = cols.object_id 
AND cols.name IN ('EntityId', 'DataClassId') 
OPEN candidateTables_cursor; 

FETCH NEXT FROM candidateTables_cursor INTO @tableName; 

WHILE @@FETCH_STATUS = 0 
BEGIN 

    DECLARE @count int; 
    DECLARE @ParmDefinition NVARCHAR(500); 

    SET @dynamicQuery = N'SELECT @countOUT = COUNT(1) FROM ' + @tableName + ' WHERE EntityId = DataclassId' 

    SET @ParmDefinition = N'@countOUT int OUTPUT' 

    sp_executeSQL(@dynamicQuery , @ParmDefinition , @[email protected] OUTPUT) 

    if @count > 0 
     PRINT @tableName 

FETCH NEXT FROM candidateTables_cursor INTO @tableName; 
END 

CLOSE candidateTables_cursor; 
DEALLOCATE candidateTables_cursor; 
+0

如何在代码中混合使用此代码?我应该将所有行写入字符串中,然后使用ExecuteReader? – Reda 2010-09-24 08:36:49

+0

首先在SQL Server Management Studio中尝试一下,看看它是否符合你的期望。如果它有效,你可以使用这段代码创建一个存储过程。但是,在存储过程中,应该除去PRINT语句,而是使用表名填充表变量,以便将其返回到代码中 – InSane 2010-09-24 08:59:13

+0

这似乎是太多工作:S我只进入了c#编码并且有一点SQL(不是我要求的)......没有其他方式只使用MVS? – Reda 2010-09-24 09:10:00

0

一个UNION ALL就够了点。

SELECT TOP 1 'Table1' FROM Table1 WHERE EntityID = DataClassID 
UNION ALL SELECT TOP 1 'Table2' FROM Table2 WHERE EntityID = DataClassID 
UNION ALL SELECT TOP 1 'Table3' FROM Table3 WHERE EntityID = DataClassID 
UNION ALL SELECT TOP 1 'Table4' FROM Table4 WHERE EntityID = DataClassID 
+0

@Lieven - 我认为这里的问题在于OP需要表名,即'Table1','Table2'等被动态获取。不要问我为什么! :-)超越我所能理解的 - 只能猜测表是在他们的数据库中动态创建的:-P – InSane 2010-09-24 09:01:36

+1

@In Sane,在这种情况下,从我能收集的内容来看,OP *应该能够通过*获得AdaTheDev在他原来的问题中提供给他的答案。我仍然认为(a)它是一个很好的起点,(b)社区已经付出足够的努力去尝试提供帮助。 – 2010-09-24 09:38:05

+0

@Lieven - 同意!我知道我已经完成了! :-) – InSane 2010-09-24 09:40:54