转换SQL语句 - 不需要游标和循环?

时间:2012-01-15 12:49:33

标签: sql sql-server

我有以下SQL语句(SQL Server):

DECLARE @atr nvarchar(255), @con nvarchar(1000), @func nvarchar(5);
SET @con='example'
SET @func=(SELECT FNCELEM FROM CNDSC WHERE NAME LIKE @con)
DECLARE Atr_Cursor CURSOR FOR
SELECT ATRBT FROM CNEA WHERE (ELEMS LIKE '%'+@func+'%' AND NOT ELEMS LIKE '%1' + @func   + '%');
OPEN Atr_Cursor;
FETCH NEXT FROM Atr_Cursor
INTO @atr;
WHILE @@FETCH_STATUS = 0
  BEGIN
    DECLARE @SQLString nvarchar(500);
    IF (SELECT COUNT(*) FROM CNEXTRA WHERE ATR LIKE ''+@atr+'' AND NAME LIKE  ''+@con+'')>0
    BEGIN
    SET @SQLString= N'SELECT NAME, ATR, CNVAL, INRDR FROM CNEXTRA WHERE ATR LIKE ''' + @atr + ''' AND NAME LIKE '''+@con+''';';
    END
    ELSE
    BEGIN
    SET @SQLString= N'SELECT '''+@con+''' AS NAME, '''+@atr+''' AS ATR, '''' AS CNVAL, '''' AS INRDR';
    END
    EXEC (@SQLString);
    FETCH NEXT FROM Atr_Cursor
    INTO @atr;
  END
CLOSE Atr_Cursor;
DEALLOCATE Atr_Cursor;

显然,由于循环,此语句会返回多个结果。在尝试将此语句与我的C#代码一起使用时,我只能得到最后一个循环的结果(显然也是如此)。所以我试着将结果转换成临时表;有效。但是现在我遇到的问题是我无法构建该语句的“补充”,因此将结果写回表中。

如果可以更改查询,以便不再有循环,我认为构建查询的补充将更容易。

所以实际上我的问题是:是否有机会更改语句,以便不再有循环?怎么会这样?如果不可能,我将如何构建该声明的补充?

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

我认为这个查询会做到这一点。

SELECT
    CNDSC.NAME,
    CNEA.ATRBT AS ATR,
    ISNULL(CNEXTRA.CNVAL,'') AS CNVAL,
    ISNULL(CNEXTRA.INRDR,'') AS INRDR
FROM
    CNDSC
    INNER JOIN CNEA
        ON CNEA.ELEMS LIKE '%'+CAST(CNDSC.FNCELEM AS VARCHAR)+'%' AND
           NOT CNEA.ELEMS LIKE '%1'+CAST(CNDSC.FNCELEM AS VARCHAR)+'%'  
    LEFT OUTER JOIN CNEXTRA
        ON CNEXTRA.ATR LIKE CNEA.ATRBT AND
           CNEXTRA.NAME LIKE @con
WHERE
    CNDSC.NAME LIKE @con;

我使用了这个架构。请告诉我哪些列错了。

CREATE TABLE CNDSC
    (NAME  VARCHAR(100), FNCELEM  VARCHAR(100));
INSERT INTO CNDSC VALUES ('ONE','FUNC1');
INSERT INTO CNDSC VALUES ('TWO','FUNC2');

CREATE TABLE CNEA
    (ATRBT VARCHAR (100), ELEMS VARCHAR(100));
INSERT INTO CNEA VALUES ('ATTRIBUTE1','FUNC1');
INSERT INTO CNEA VALUES ('ATTRIBUTE2','FUNC2');

CREATE TABLE CNEXTRA
    (ATR VARCHAR(100),
     NAME VARCHAR(100),
     CNVAL  VARCHAR(100),
     INRDR  VARCHAR(100));
INSERT INTO CNEXTRA VALUES ('ATTRIBUTE1','ONE','CNVAL','INRDR');