子查询在临时表存储过程中返回了多个值

时间:2016-06-27 06:26:04

标签: sql-server stored-procedures temp-tables

当我执行我的存储过程时,它会显示此错误

  

'子查询返回的值超过1。这是不允许的   子查询跟随=,!=,<,< =,>,> =或当子查询用作   表达'。怎么解决这个问题?

存储过程:

ALTER PROCEDURE [dbo].[SPEMPIDDETAILS]
AS
BEGIN
    DECLARE @INTSTART AS INTEGER;
    DECLARE @INTSTOP AS INTEGER;

    DECLARE @PREFNO AS VARCHAR(50);
    DECLARE @PVAL AS DATE;

    DECLARE @VREFNO AS VARCHAR(50);
    DECLARE @VVAL AS DATE;

    DECLARE @SBREFNO AS VARCHAR(50);
    DECLARE @SBVAL AS VARCHAR(50);

    DECLARE @UVREFNO AS VARCHAR(50);
    DECLARE @UVVAL AS DATE;

    DECLARE @TEMPTABLEEMP TABLE (PREFNO VARCHAR(50),
                                 PVAL DATE, VREFNO VARCHAR(50),
                                 VVAL DATE, SBREFNO VARCHAR(50),
                                 SBVAL DATE, UVREFNO VARCHAR(50), UVVAL DATE)

    SELECT @INTSTART = 1;
    SELECT @INTSTOP = (SELECT COUNT(PK_ID) FROM EMPIDDETAILS);

    WHILE @INTSTART <= @INTSTOP
    BEGIN
        SELECT 
            @PREFNO = (SELECT REF_NO FROM EMPIDDETAILS  
                       WHERE DOCUMENT_TYPE = 'PASSPORT'),
            @PVAL = (SELECT VALIDITY FROM EMPIDDETAILS 
                     WHERE DOCUMENT_TYPE = 'PASSPORT')
        --GROUP BY EMPIDDETAILS.EMPLOYE

        SELECT 
            @VREFNO = (SELECT REF_NO FROM EMPIDDETAILS 
                       WHERE DOCUMENT_TYPE = 'VISA'),
            @VVAL = (SELECT VALIDITY FROM EMPIDDETAILS 
                     WHERE DOCUMENT_TYPE = 'VISA')

        SELECT 
            @SBREFNO = (SELECT REF_NO FROM EMPIDDETAILS 
                        WHERE DOCUMENT_TYPE = 'SEAMAN BOOK'),
            @SBVAL = (SELECT VALIDITY FROM EMPIDDETAILS 
                      WHERE DOCUMENT_TYPE = 'SEAMAN BOOK')

        SELECT 
            @UVREFNO = (SELECT REF_NO FROM EMPIDDETAILS 
                        WHERE DOCUMENT_TYPE = 'USVISA'),
            @UVVAL = (SELECT VALIDITY FROM EMPIDDETAILS 
                      WHERE DOCUMENT_TYPE = 'USVISA')

        INSERT INTO @TEMPTABLEEMP 
        VALUES(@PREFNO, @PVAL, @VREFNO, @VVAL, @SBREFNO, @SBVAL, @UVREFNO, @UVVAL)

        SET @PREFNO = 0
        SET @PVAL = NULL
        SET @VREFNO = 0
        SET @VVAL = NULL
        SET @SBREFNO = 0
        SET @SBVAL = NULL
        SET @UVREFNO = 0
        SET @UVVAL = NULL

        SET @INTSTART = @INTSTART + 1;
    END

    SELECT 
        PREFNO, PVAL, VREFNO, VVAL, SBREFNO, SBVAL, UVREFNO, UVVAL 
    FROM @TEMPTABLEEMP
END

5 个答案:

答案 0 :(得分:0)

在不了解您的数据的情况下,很难说,但您尝试将查询结果分配给值。如果查询,例如

,该怎么办?
SELECT @PREFNO=(SELECT REF_NO FROM EMPIDDETAILS WHERE DOCUMENT_TYPE='PASSPORT')

返回多个文件类型的护照?这可以应用于您希望将值存储在变量中的所有查询。

答案 1 :(得分:0)

您正在使用select语句为变量赋值。有些时候,根据您的过滤器可能存在多个记录。请检查您的Document_Type过滤器,其中一个过滤器返回多个值。为了避免这种情况,您可以使用&#34; Top 1&#34;

参考,

ALTER PROCEDURE [dbo].[SPEMPIDDETAILS]
AS
BEGIN
    DECLARE @INTSTART AS INTEGER;
    DECLARE @INTSTOP AS INTEGER;
    DECLARE @PREFNO AS VARCHAR(50);
    DECLARE @PVAL AS DATE;
    DECLARE @VREFNO AS VARCHAR(50);
    DECLARE @VVAL AS DATE;
    DECLARE @SBREFNO AS VARCHAR(50);
    DECLARE @SBVAL AS VARCHAR(50);
    DECLARE @UVREFNO AS VARCHAR(50);
    DECLARE @UVVAL AS DATE;
    DECLARE @TEMPTABLEEMP TABLE (
        PREFNO VARCHAR(50)
        ,PVAL DATE
        ,VREFNO VARCHAR(50)
        ,VVAL DATE
        ,SBREFNO VARCHAR(50)
        ,SBVAL DATE
        ,UVREFNO VARCHAR(50)
        ,UVVAL DATE
        )

    SELECT @INTSTART = 1;

    SELECT @INTSTOP = (
            SELECT COUNT(PK_ID)
            FROM EMPIDDETAILS
            );

    WHILE @INTSTART <= @INTSTOP
    BEGIN
        SELECT @PREFNO = (
                SELECT TOP 1 REF_NO
                FROM EMPIDDETAILS
                WHERE DOCUMENT_TYPE = 'PASSPORT'
                )
            ,@PVAL = (
                SELECT TOP 1 VALIDITY
                FROM EMPIDDETAILS
                WHERE DOCUMENT_TYPE = 'PASSPORT'
                )

        --GROUP BY EMPIDDETAILS.EMPLOYE
        SELECT @VREFNO = (
                SELECT TOP 1 REF_NO
                FROM EMPIDDETAILS
                WHERE DOCUMENT_TYPE = 'VISA'
                )
            ,@VVAL = (
                SELECT TOP 1 VALIDITY
                FROM EMPIDDETAILS
                WHERE DOCUMENT_TYPE = 'VISA'
                )

        SELECT @SBREFNO = (
                SELECT TOP 1 REF_NO
                FROM EMPIDDETAILS
                WHERE DOCUMENT_TYPE = 'SEAMAN BOOK'
                )
            ,@SBVAL = (
                SELECT TOP 1 VALIDITY
                FROM EMPIDDETAILS
                WHERE DOCUMENT_TYPE = 'SEAMAN BOOK'
                )

        SELECT @UVREFNO = (
                SELECT TOP 1 REF_NO
                FROM EMPIDDETAILS
                WHERE DOCUMENT_TYPE = 'USVISA'
                )
            ,@UVVAL = (
                SELECT TOP 1 VALIDITY
                FROM EMPIDDETAILS
                WHERE DOCUMENT_TYPE = 'USVISA'
                )

        INSERT INTO @TEMPTABLEEMP
        VALUES (
            @PREFNO
            ,@PVAL
            ,@VREFNO
            ,@VVAL
            ,@SBREFNO
            ,@SBVAL
            ,@UVREFNO
            ,@UVVAL
            )

        SET @PREFNO = 0
        SET @PVAL = NULL
        SET @VREFNO = 0
        SET @VVAL = NULL
        SET @SBREFNO = 0
        SET @SBVAL = NULL
        SET @UVREFNO = 0
        SET @UVVAL = NULL
        SET @INTSTART = @INTSTART + 1;
    END

    SELECT PREFNO
        ,PVAL
        ,VREFNO
        ,VVAL
        ,SBREFNO
        ,SBVAL
        ,UVREFNO
        ,UVVAL
    FROM @TEMPTABLEEMP
END

答案 2 :(得分:0)

您可以做的最好的事情是为用于分配给变量的所有子查询添加TOP(1)子句

答案 3 :(得分:0)

有些表格中的数据有重复值。例如在行

// Make sure the URL string isn't too long.
// We're limiting it to 2GB for backwards compatibility with 32-bit executables using NS/CFURL
if ( (urlStringLength > 0) && (urlStringLength <= INT_MAX) )
{
...

当您说NSString *path = [@"a:" stringByPaddingToLength:314572800 withString:@"a" startingAtIndex:0]; NSString *js = [NSString stringWithFormat:@"window.location.href = \"%@\";", path]; [self.webView stringByEvaluatingJavaScriptFromString:js]; 时,可能会出现两个- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { NSLog(@"length: %@", @(request.URL.absoluteString.length)); return YES; } 具有相同SELECT @PREFNO=(SELECT REF_NO FROM EMPIDDETAILS WHERE DOCUMENT_TYPE='PASSPORT'),@PVAL=(SELECT VALIDITY FROM EMPIDDETAILS WHERE DOCUMENT_TYPE='PASSPORT') 的情况,从而为您提供两个结果。

为了避免这种情况,您必须添加另一个条件,您可以说它没有重复值(可能是主键)或添加SELECT REF_NO FROM EMPIDDETAILS WHERE DOCUMENT_TYPE='PASSPORT'以确保查询只返回一个数据。

REF_NO

现在有时候查询返回的数据不是您期望的数据。因此,您可以考虑添加DOCUMENT_TYPE子句,以便从查询中获取的第一个数据是您想要的所需数据。

示例:

TOP 1

上述示例仅检索SELECT @PREFNO=(SELECT TOP 1 REF_NO FROM EMPIDDETAILS WHERE DOCUMENT_TYPE='PASSPORT'),@PVAL=(SELECT TOP 1 VALIDITY FROM EMPIDDETAILS WHERE DOCUMENT_TYPE='PASSPORT') 具有最高ORDER BY,考虑到SELECT @PREFNO=(SELECT TOP 1 REF_NO FROM EMPIDDETAILS WHERE DOCUMENT_TYPE='PASSPORT' ORDER BY pk_id DESC) REF_NO数据类型为pk_id

更新:如果具有相同pk_id的数据完全相同,则另一件事就是添加primary key

答案 4 :(得分:0)

实际上不需要光标。看看具有相同输出的两种方法。您的主要问题是您将@INTSTART声明为EMP的ID但未在过滤器中使用它。

DECLARE @EMPIDDETAILS TABLE 
(
    PK_ID INT NOT NULL,
    REF_NO VARCHAR(100) NOT NULL,
    DOCUMENT_TYPE VARCHAR(100) NOT NULL,
    VALIDITY BIT NOT NULL
)

INSERT INTO @EMPIDDETAILS (PK_ID, REF_NO, DOCUMENT_TYPE, VALIDITY)
VALUES
(1, '111-VISA', 'VISA', 1),
(1, '111-PASS', 'PASSPORT', 1),
(2, '222-PASS', 'PASSPORT', 0),
(2, '222-SEEA', 'SEAMAN BOOK', 1),
(2, '222-VISA', 'VISA', 1),
(2, '222-USVS', 'USVISA', 0)


SELECT
    ed.PK_ID,
    MAX(CASE WHEN ed.DOCUMENT_TYPE = 'PASSPORT' THEN ed.REF_NO END) AS PREFNO,
    MAX(CASE WHEN ed.DOCUMENT_TYPE = 'PASSPORT' THEN CAST(ed.VALIDITY AS INT) END) AS PVAL, 
    MAX(CASE WHEN ed.DOCUMENT_TYPE = 'VISA' THEN ed.REF_NO END) AS VREFNO,
    MAX(CASE WHEN ed.DOCUMENT_TYPE = 'VISA' THEN CAST(ed.VALIDITY AS INT) END) AS VVAL, 
    MAX(CASE WHEN ed.DOCUMENT_TYPE = 'SEAMAN BOOK' THEN ed.REF_NO END) AS SBREFNO,
    MAX(CASE WHEN ed.DOCUMENT_TYPE = 'SEAMAN BOOK' THEN CAST(ed.VALIDITY AS INT) END) AS SBVAL, 
    MAX(CASE WHEN ed.DOCUMENT_TYPE = 'USVISA' THEN ed.REF_NO END) AS UVREFNO,
    MAX(CASE WHEN ed.DOCUMENT_TYPE = 'USVISA' THEN CAST(ed.VALIDITY AS INT) END) AS UVVAL 
FROM @EMPIDDETAILS ed 
GROUP BY ed.PK_ID


SELECT
    pv.PK_ID,
    MAX([PASSPORT]) AS [PASSPORT],
    MAX([PASSPORT-VALIDITY]) AS [PASSPORT-VALIDITY], 
    MAX([VISA]) AS [VISA],
    MAX([VISA-VALIDITY]) AS [VISA-VALIDITY], 
    MAX([SEAMAN BOOK]) AS [SEAMAN BOOK],
    MAX([SEAMAN BOOK-VALIDITY]) AS [SEAMAN BOOK-VALIDITY], 
    MAX([USVISA]) AS [USVISA],
    MAX([USVISA-VALIDITY]) AS [USVISA-VALIDITY] 
FROM 
(
    SELECT
        ed.PK_ID, ed.REF_NO, ed.DOCUMENT_TYPE,
        CAST(ed.VALIDITY AS INT) AS VALIDITY,
        ed.DOCUMENT_TYPE+'-VALIDITY' as REF_VAL 
    FROM @EMPIDDETAILS ed
) ed
PIVOT
(
    MAX(ed.REF_NO)
    FOR ed.DOCUMENT_TYPE IN ([VISA], [PASSPORT], [SEAMAN BOOK], [USVISA])
) pr
PIVOT
(
    MAX(pr.VALIDITY)
    FOR pr.REF_VAL IN ([VISA-VALIDITY], [PASSPORT-VALIDITY], [SEAMAN BOOK-VALIDITY], [USVISA-VALIDITY])
) pv
GROUP BY pv.PK_ID

最后只需插入你的temptable或做任何你想做的事。

enter image description here