Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[SQL] Operator in query laten afhangen van IF-statement

Pagina: 1
Acties:

  • Urk
  • Registratie: Maart 2000
  • Laatst online: 17-11 00:43
Wederom een SQL vraagje waar ik veel over gezocht heb maar toch niet uitkom:

Ik heb de volgende query (even ingekort):
SQL:
1
2
3
SELECT omzet_jaarmaand
FROM omzetten
WHERE omzetten.omzet_segment_uid = @segment


Nu heb ik een multi-statement table-valued functie geschreven, zie hieronder een ingekorte versie:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CREATE FUNCTION [dbo].[testfunctie] (
 @segment varchar(11) = 'IS NOT NULL'
)

RETURNS @resulttable TABLE (
 omzet_bedrag int
)
AS
BEGIN

IF ISNUMERIC(@segment) = 1
 SET @segment = '= '+@segment

INSERT @resulttable

SELECT omzet_bedrag
FROM omzetten
WHERE omzetten.omzet_segment_uid = @segment

RETURN

END


Wanneer ik deze functie nu aanroep zonder parameters wordt de default waarde voor @segment genomen. Die heb ik ingesteld op 'IS NOT NULL' wat neerkomt op alle waarden (want deze waarde is nooit null), echter komt dan in de query:
SQL:
1
WHERE omzetten.omzet_segment_uid = IS NOT NULL

En de = operator voor IS NOT NULL kan niet. Ik kan deze operator niet weghalen want als er wel een int waarde voor @segment wordt toegekend aan de functie wil ik dat de query blijft kloppen.
Na veel lezen hierover op internet las ik dat het niet mogelijk is om een EXEC statement te draaien, zoals bijv.

SQL:
1
2
3
4
5
6
DECLARE @sql varchar(2000)

SET @sql = 'SELECT omzet_bedrag
FROM omzetten
WHERE omzetten.omzet_segment_uid '+@segment
EXEC(@sql)


Hoe kan ik er dus voor zorgen dat wanneer de functie zonder @segment parameter wordt aangeroepen alle records worden teruggegeven en wanneer ik wel een @segment parameter waarde (=integer) invoer ik alleen de records krijg met die waarde? _/-\o_
Hoop dat alles duidelijk is hierboven...

Documentatie die ik o.a. heb nageslagen op internet hierover zijn:
http://www.sommarskog.se/dynamic_sql.html
http://www.informit.com/a...le.aspx?p=130855&seqNum=3
http://doc.ddart.net/mssq...tedb/cm_8_des_08_361x.htm

[ Voor 6% gewijzigd door Urk op 25-03-2008 15:13 ]


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Doe je niet heel erg moeilijk om niets?

SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Create PROCEDURE [dbo].[MyProcedure] 
  @Foo as int,
  @Bar as int
AS
BEGIN
  If @Foo = 1337
    Select something
    From MyTable
    Where blah >= @bar
  else
    Select something
    From MyTable
    Where blah is null
end


Waarom dynamisch, in SQL, een query gaan bouwen en die met EXEC uitvoeren als je met een simpele 'gewone' IF al een heel eind komt in een SP.

Verder moet wat jij wil wel kunnen volgens mij (dynamisch een string opbouwen), alleen is je @Segment null als je 'm niet meegeeft en dat concatenaten (met de + operator) aan je @sql zal niet lukken; in dat geval maak je 'm dus gewoon '' (ofwel: ...WHERE omzetten.omzet_segment_uid ' + IsNull(@Sql,'') of ...WHERE omzetten.omzet_segment_uid ' + IsNull(@Sql,' is null')

[ Voor 48% gewijzigd door RobIII op 25-03-2008 15:20 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 08-11 20:21

Skinny

DIRECT!

SQL:
1
2
3
4
5
6
7
8
9
DECLARE @segment int = NULL

SELECT omzet_jaarmaand 
FROM omzetten 
WHERE   (
        (@segment IS NOT NULL AND omzetten.omzet_segment_uid = @segment  )
        OR
        (@segment IS NULL)
    )



Als je de param dus niet meegeeft nu geeft ie alles terug. Bij een waarde voor @segment ongelijk aan NULL past ie de juiste join toe.

[ Voor 6% gewijzigd door Skinny op 25-03-2008 15:27 ]

SIZE does matter.
"You're go at throttle up!"


  • Urk
  • Registratie: Maart 2000
  • Laatst online: 17-11 00:43
RobIII schreef op dinsdag 25 maart 2008 @ 15:15:
Doe je niet heel erg moeilijk om niets?

SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Create PROCEDURE [dbo].[MyProcedure] 
  @Foo as int,
  @Bar as int
AS
BEGIN
  If @Foo = 1337
    Select something
    From MyTable
    Where blah >= @bar
  else
    Select something
    From MyTable
    Where blah is null
end


Waarom dynamisch, in SQL, een query gaan bouwen en die met EXEC uitvoeren als je met een simpele 'gewone' IF al een heel eind komt in een SP.
Bedankt voor je reactie! _/-\o_
Je hebt wel gelijk maar de query is in werkelijkhied een stuk langer (zo'n 20 regels) en daarbij heb ik ook meerdere parameters (6 stuks), dus dan krijg ik heel wat if of case statements...en wordt m'n functie honderden regels lang. Dat moet dan toch ook anders kunnen?
Is er een andere oplossing?

  • Urk
  • Registratie: Maart 2000
  • Laatst online: 17-11 00:43
Skinny schreef op dinsdag 25 maart 2008 @ 15:19:
SQL:
1
2
3
4
5
6
7
8
9
DECLARE @segment int = NULL

SELECT omzet_jaarmaand 
FROM omzetten 
WHERE   (
        (@segment IS NOT NULL AND omzetten.omzet_segment_uid = @segment  )
        OR
        (@segment IS NULL)
    )

Als je de param dus niet meegeeft nu geeft ie alles terug. Bij een waarde voor @segment ongelijk aan NULL past ie de juiste join toe.
Damn...dat werkt perfect, wist niet dat dat op die manier kon... _/-\o_

Toch begrijp ik het niet helemaal, als ik bovenstaande logisch lees kom ik op het volgende:
Als @segment NIET NULL is, dan is er dus een integer waarde aan de functie meegegeven voert hij
(@segment IS NOT NULL AND omzetten.omzet_segment_uid = @segment) uit.

Echter als ik geen waarde meegeef komt de 2e statment die zegt @segment IS NULL, maar de waardes zijn NOOIT NULL, toch geeft hij dan alle records terug. Wel wat ik wil maar ik begrijp de logica niet... |:(

  • P.O. Box
  • Registratie: Augustus 2005
  • Niet online
het gaat er niet om dat de waardes NULL zijn, maar je parameter
Pagina: 1