locked
Dinamikus SQL lekérdezés és "NOT IN" RRS feed

  • Question

  • Sziasztok!

    Az alábbi dinamikusan összerakott tsql selectet szeretném lefuttatni úgy, hogy a  @StatusId-ben adok meg egy "IN (x,x,x)" vagy "NOT IN (x,x,x)" kifejezésdarabot. Az SQL a következő hibával hajt el: Msg 102, Level 15, State 1, Line 8 Incorrect syntax near '@ST'.

    Van ötletetek, hogy hogyan lehetne a leg egyszerűbben megoldani, hogy egy

    Az egész háttere, egy tárolt eljárás, amit programból hívnék meg. Az tsql lekérdezést dinamikusan építem fel benne és a végén futtatom az sp_executesql-el. Itt már csak az összerakott tsql utasítást emeltem ki. Az egész lényege az utolsó sor.

    Köszönöm,
    István

     

    DECLARE @userCompany int = 3,
    @StatusId varchar(20) = N'NOT IN (16,4,64)',
    @sql nvarchar(4000)

     

     

     

    SET @sql =
    N'SELECT TicketId, hdt.Company, Subject, CreatorName, hds.StatusDesc, hdp.PriorityDesc, CreatedTime, ClosedTime, AssignedUser
    FROM HD_Ticket AS hdt
    JOIN HD_Priority AS hdp ON hdt.PriorId = hdp.PriorId
    JOIN HD_Status AS hds ON hdt.StatusId = hds.StatusId
    JOIN HD_Company AS hdc ON hdt.Company = hdc.CompanyCod
    WHERE 1=1 AND
    hdc.CompanyInt IN (SELECT * FROM dbo.getusermembership(@UC)) AND
    hdt.StatusId @ST'

    EXEC

     

    sp_executesql @sql, N'@UC AS int, @ST AS varchar(20)', @UC = @userCompany, @ST = @StatusId;

    • Moved by Othorvath Saturday, January 16, 2010 2:38 PM (From:Altalanos SQL kerdesek)
    Saturday, August 29, 2009 12:27 PM

Answers


  • Hello!
    Több megoldás van, attól függően, hogy honnan származik az IN vagy NOT IN mögötti értéklista.

    1. Kószó Károly arra gondolt, hogy ha az IN listájában lévő értékek egy lekérdezésből vagy táblából (pl. Lista) származnak, csak szerintem nem jól fogalmazta meg:
    DECLARE @StatusID varchar(1000)
    DECLARE @SQL varchar(4000)
    
    SELECT @StatusID = ''
    SELECT @StatusID = @StatusID + ISNULL(Ertek, '') + ',' FROM Lista
    SET @StatusID = 'IN (' + LEFT(@StatusID, LEN(@StatusID) - 1) + ')'
    SET @SQL = 'SELECT a FROM Table1 WHERE b ' + @StatusID
    EXEC sp_executesql @SQL

    2. Ha a lista már megvan valahonnan egy stringben (ez a legegyszerűbb):
    DECLARE @StatusID varchar(1000)
    DECLARE @SQL varchar(4000)
    
    SET @StatusID = 'IN (1, 2, 3)'
    -- vagy
    SET @StatusID = 'NOT IN (1, 2, 3)'
    SET @SQL = 'SELECT a FROM Table1 WHERE b ' + @StatusID
    EXEC sp_executesql @SQL

    3. Nekem vagy egy olyan függvényem, amely táblává alakít egy felsorolt listát, ezzel így lehet megoldani:

    SELECT a FROM Table1 T INNER JOIN dbo.Split('1,2,3') S
          ON T.b = S.Item
    -- vagy
    SELECT a FROM Table1 WHERE b IN (SELECT Item FROM dbo.Split('1,2,3'))
    Friday, September 4, 2009 3:01 PM

All replies

  • Az sp_executesql csak ott fogad el paramétert, ahol az SQL-ben általában megengedett.
    Nem lehet paraméter pl. táblanév, vagy egy záradék.
    Az alábbi - nem túl szép - megoldás működik:

    use

    tempdb
    create table t(a int)
    go

    DECLARE

    @StatusId varchar(20) = N'NOT IN (16,4,64)', @sql nvarchar(4000)
    SET @sql =N'SELECT a FROM t WHERE 1=1 AND a ' + @StatusId
    EXEC sp_executesql @sql

    -- Károly


    Károly
    Monday, August 31, 2009 5:50 PM
  • Szia!

    Köszönöm a magyarázatot.
    A megoldásodat nem teljesen értemm. Létrehozok egy táblát, de mit csinálok vele?

    Nem arra gondolsz, hogy ebbe töltöm fel a zárojelben lévő azonosítókat?

    István
    Tuesday, September 1, 2009 10:26 AM

  • Hello!
    Több megoldás van, attól függően, hogy honnan származik az IN vagy NOT IN mögötti értéklista.

    1. Kószó Károly arra gondolt, hogy ha az IN listájában lévő értékek egy lekérdezésből vagy táblából (pl. Lista) származnak, csak szerintem nem jól fogalmazta meg:
    DECLARE @StatusID varchar(1000)
    DECLARE @SQL varchar(4000)
    
    SELECT @StatusID = ''
    SELECT @StatusID = @StatusID + ISNULL(Ertek, '') + ',' FROM Lista
    SET @StatusID = 'IN (' + LEFT(@StatusID, LEN(@StatusID) - 1) + ')'
    SET @SQL = 'SELECT a FROM Table1 WHERE b ' + @StatusID
    EXEC sp_executesql @SQL

    2. Ha a lista már megvan valahonnan egy stringben (ez a legegyszerűbb):
    DECLARE @StatusID varchar(1000)
    DECLARE @SQL varchar(4000)
    
    SET @StatusID = 'IN (1, 2, 3)'
    -- vagy
    SET @StatusID = 'NOT IN (1, 2, 3)'
    SET @SQL = 'SELECT a FROM Table1 WHERE b ' + @StatusID
    EXEC sp_executesql @SQL

    3. Nekem vagy egy olyan függvényem, amely táblává alakít egy felsorolt listát, ezzel így lehet megoldani:

    SELECT a FROM Table1 T INNER JOIN dbo.Split('1,2,3') S
          ON T.b = S.Item
    -- vagy
    SELECT a FROM Table1 WHERE b IN (SELECT Item FROM dbo.Split('1,2,3'))
    Friday, September 4, 2009 3:01 PM
  • Szia!

    Kösz, ez a string függvényes jó ötelt. Táblát tudtommal nem lehet átadni tárolt eljárásnak, csak kis munka árán, úgyhogy egyszerűbb is.

    Köszönöm,
    István
    Friday, September 4, 2009 3:05 PM