代码之家  ›  专栏  ›  技术社区  ›  Ed Sinek

我需要光标吗?

  •  0
  • Ed Sinek  · 技术社区  · 16 年前

    只需在前面说,我正在使用一个现有的模式(这不是最好的),我无法控制它。我必须处理它-我一点也改变不了。

    每个公司都有一个记录的公司表,然后每个公司都有自己的一组表来表示业务操作。首先,我对每个公司的特定表感兴趣。我的任务是从所有公司MyTables中生成一个记录集输出

    这是我的样品:

    CREATE TABLE [dbo].[Company](
        [timestamp] [timestamp] NOT NULL,
        [Name] [varchar](30) NOT NULL,
        [Short Code] [varchar](3) NOT NULL,
    CONSTRAINT [Company$0] PRIMARY KEY CLUSTERED([Name] ASC))
    

    如果我从Company表中选择所有名称,我将得到(例如)
    A、B、C公司。

    然后,我为每个公司都有一个表(所有公司特定的表都有完全相同的列定义),名称如下(在公司名称中:保留空格,句点改为下划线):

    CREATE TABLE [dbo].[Company A$MyTable](
        --Various columns
    )
    

    “MyTable”是指“Company C Inc.”的名称是[Company C Inc$MyTable]

    我想在一个存储过程中执行T-SQL,然后从显示数据的C代码中使用它。

    由于我有限的SQL技能,我猜我需要使用游标。因为我对草书不太在行,我希望这里的人能给我一个开头。

    谢谢,
    --编辑

    2 回复  |  直到 16 年前
        1
  •  3
  •   RC_Cleland    16 年前

    这里有一个不使用游标的方法。它基于一个方法,该方法使用“FOR XMLPATH”将值列表转换为字符串

    declare @Table4Company table(CoName varchar(30))
    declare @sqlCMD varchar(max)
    Insert @Table4Company Select distinct (Name) from Company
    Select @sqlCMD =
    (SELECT
      STUFF(
        (
        SELECT
          'UNION  Select * from [' + REPLACE(CoName,'.','_') + '$MyTable]'
        FROM @Table4Company
        FOR XML PATH('')
        ), 1, 6, ''
      )
    )
    --Select @sqlCMD
    

    您没有说明您支持的SQL的哪个版本,并且上面的代码不会在每个版本中都工作。我在SQL2K8中测试了上面的代码。

    顺便问一下,每次添加新公司时,谁创建新的公司名称表?

        2
  •  2
  •   Raymund    16 年前

    试试这个,只要您的所有[公司A$MyTable]的表结构都相同,这个就可以了

    DECLARE @TableName as nvarchar(max)
    DECLARE @StringSQL as nvarchar(max) = ''
    DECLARE MY_CURSOR Cursor 
    FOR 
    SELECT  INFORMATION_SCHEMA.COLUMNS.TABLE_NAME
    FROM INFORMATION_SCHEMA.COLUMNS INNER JOIN
    Company ON INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = Company.Name 
    
    OPEN  MY_CURSOR
    FETCH NEXT FROM MY_CURSOR
    INTO @TableName
    WHILE @@FETCH_STATUS = 0
        BEGIN
    
            SET @StringSQL = @StringSQL + 'Select ''' + @TableName + ''', * from [' + @TableName + '$MyTable] UNION '
            --PRINT @StringSQL
            FETCH NEXT FROM MY_CURSOR INTO @TableName
        END
    CLOSE MY_CURSOR
    DEALLOCATE MY_CURSOR
    --This removes the last union
    SET @StringSQL= LEFT(@StringSQL,LEN(@StringSQL)-6)
    EXECUTE  (@StringSQL)