Article View: pl.comp.bazy-danych
Article #195608Re: Dziwne zmienne w MS-SQL
From: Adam
Date: Sat, 16 Jun 2018 10:45
Date: Sat, 16 Jun 2018 10:45
362 lines
14062 bytes
14062 bytes
W dniu 2018-06-15 o 18:03, Stokrotka pisze:
>
>
>> Dlaczego zmienne w pewnych sytuacjach nie działają jak zmienne?
>>
>> Przykład _NIE_ działający:
>>
>> use master
>>
>> declare @TaBelKa nvarchar(40)
>> set @TaBelKa = 'sys.tables'
>> select * from @TaBelKa
>>
>> Zmienna niby jest "napompowana" wartością, gdyż select @TaBelKa
>> zwraca wartość prawidłową.
>>
>>
>> Dlaczego trzeba tworzyć jakieś karkołomne konstrukcje typu:
>>
>> use master
>>
>> declare @TaBelKa nvarchar(40)
>> set @TaBelKa = 'sys.tables'
>> DECLARE @SQL NVARCHAR(100)
>> SET @SQL = N'SELECT * FROM ' + @TaBelKa
>> EXECUTE sp_executesql @SQL
>>
>>
>> Ki diabeł?
>> O co chodzi?
>>
> Wydaje mi się, że coś utrudniasz.
Może4sz wyjaśnić znaczenie "utrudniasz"?
> Według mnie pierwszy pszykład nie powinien iść,
Uzasadnienie?
Zakładam zmienną:
declare @TaBelKa nvarchar(40)
Wypełniam wartością:
set @TaBelKa = 'sys.tables'
Sprawdzam, czy wartość jest:
select @TaBelKa
Zwraca prawidłową wartość.
Więc nieco inaczej, np:
select 'wartość zmiennej: ' + @TaBelKa + ', a dzisiaj mamy ' +
convert(nvarchar(MAX), GETDATE(), 20)
też wartości zwracane prawidłowo.
Dlaczego więc nie działa tu:
select * from @TaBelKa
Znaczy: widzę, że zgłasza niezgodność zmiennej. Ale dlaczego?
Jeśli tabela ma kilka kolumn, to nie ma problemu - można deklarować. Ale
jeśli tabel jest ok. 300, a w niektórych po kilkadziesiąt i więcej
kolumn, to zaczyna się problem.
> a drugi to jakaś skomplikowana kopia
> z jakiegoś pszykładu, gdzie nie wszystko jest niezbędne.
O czym Ty piszesz? Jaka kopia? Z palca pisałem.
Możesz powiedzieć, co jest niepotrzebne? Chętnie się dowiem, bo o to mi
chodzi.
Sprawdzałem na MS-SQL od 2005 do 2016. Starszych nie sprawdzałem, już
raczej nie ma potrzeby.
Teraz - dlaczego pytam.
Otóż, konstruując większe zapytania i korzystając z konstrukcji
SET @SQL = N'
to w edytorze Management Studio wszystko po znaku ['] już nie jest
kontrolowane względem składni.
Rodzi to możliwość popełnienia błędów choćby literowych, a znaleźć taki
w większych zapytaniach to problem.
Poniżej przykład jednego z zapytań, niezbyt zresztą długiego:
=============================================
DECLARE @DATA12 datetime;
set @DATA12 = '20120101';
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
--Wyliczanie poziomów grup produktów
WITH g(gid, gidTyp, kod, gidNumer, grONumer, poziom, sciezka)
AS
(
SELECT TwG_TwGID, TwG_GIDTyp, TwG_Kod, TwG_GIDNumer,
TwG_GrONumer, 0 as poziom, convert(nvarchar(1024), '') as sciezka
FROM CDN.TwrGrupy
WHERE TwG_TwGID = 0
UNION ALL
SELECT TwG_TwGID, TwG_GIDTyp, TwG_Kod, TwG_GIDNumer,
TwG_GrONumer, p.poziom + 1 as poziom, convert(nvarchar(1024), p.sciezka
+ N'\' + c.TwG_Kod) as sciezka
FROM g p
JOIN CDN.TwrGrupy c
ON c.TwG_GrONumer = p.gidNumer
WHERE c.TwG_TwGID <> 0 AND c.TwG_GIDTyp = -16
)
SELECT * INTO #tmpTwrGr FROM g
DECLARE @poziom int
DECLARE @poziom_max int
DECLARE @sql nvarchar(max)
SELECT @poziom_max = MAX(poziom) FROM #tmpTwrGr
SET @poziom = @poziom_max
SET @sql = N''
WHILE @poziom >= 0
BEGIN
SET @sql = N'ALTER TABLE #tmpTwrGr ADD Poziom' + CAST(@poziom AS
nvarchar) + N' nvarchar(40), ONr' + CAST(@poziom AS nvarchar) + N'
nvarchar(40)'
EXEC(@sql)
IF @poziom = @poziom_max
BEGIN
SET @sql = N'UPDATE #tmpTwrGr
SET ONr' + CAST(@poziom AS nvarchar) + '= grONumer '
EXEC(@sql)
SET @sql = N'UPDATE #tmpTwrGr
SET Poziom' + CAST(@poziom AS nvarchar) + ' = kod'
EXEC(@sql)
END
ELSE
BEGIN
SET @sql = N'UPDATE c
SET c.Poziom' + CAST(@poziom AS nvarchar) + N' = (
CASE WHEN c.poziom <=' + CAST(@poziom AS nvarchar) + N' THEN
CAST(c.kod AS nvarchar)
ELSE CAST(p.kod AS nvarchar) END)
FROM #tmpTwrGr c
LEFT JOIN #tmpTwrGr p
ON c.ONr' + CAST(@poziom + 1 AS nvarchar) + '= p.gidNumer '
EXEC(@sql)
SET @sql = N'UPDATE c
SET c.ONr' + CAST(@poziom AS nvarchar) + N' = (
CASE WHEN c.poziom <=' + CAST(@poziom AS nvarchar) + N' THEN
CAST(c.grONumer AS nvarchar)
ELSE CAST(p.grONumer AS nvarchar) END)
FROM #tmpTwrGr c
LEFT JOIN #tmpTwrGr p
ON c.ONr' + CAST(@poziom + 1 AS nvarchar) + '= p.gidNumer '
EXEC(@sql)
END
SET @poziom = @poziom - 1
END
declare @select varchar(max)
declare @kolumny varchar(max)
declare @kolumny2 varchar(max)
declare @i int
set @kolumny = ''
set @kolumny2 = ''
set @i=0
while (@i<=@poziom_max)
begin
set @kolumny = @kolumny + ',"Produkt Grupa Poziom ' + LTRIM(@i) + '" =
CASE WHEN Poz.Poziom' +LTRIM(@i) + ' IS NULL THEN ''(NIEPRZYPISANE)''
ELSE Poz.Poziom' + LTRIM(@i) + ' END'
set @kolumny2 = @kolumny2 + ',Poz.Poziom' +LTRIM(@i)
set @i = @i + 1
end
--W³aœciwe zapytanie
set @select =
'SELECT
DB_NAME() [Baza Firmowa],
MAX(Twr_Kod) [Produkt Kod],
25003 [Produkt Kod __PROCID__Towary__], Twr_twrId [Produkt Kod __ORGID__],
MAX(Twr_Nazwa) [Produkt Nazwa],
25003 [Produkt Nazwa __PROCID__], Twr_twrId [Produkt Nazwa __ORGID__],
MAX(CASE
WHEN Twr_Typ = 0 AND Twr_Produkt = 0 THEN ''Us³uga Prosta''
WHEN Twr_Typ = 1 AND Twr_Produkt = 0 THEN ''Towar Prosty''
WHEN Twr_Typ = 0 AND Twr_Produkt = 1 THEN ''Us³uga Z³o¿ona''
WHEN Twr_Typ = 1 AND Twr_Produkt = 1 THEN ''Towar Z³o¿ony''
ELSE ''(NIEOKREŒLONY)''
END) [Produkt Typ],
ISNULL(MAX(Kat_KodOgolny),''(NIEOKREŚLONA)'') [Produkt Kategoria
Ogólna], ISNULL(MAX(Kat_KodSzczegol),''(NIEOKREŚLONA)'') [Produkt
Kategoria Szczegółowa], MAX(Twr_JM) [Jednostka Miary],
"Ilość Stan Początkowy H"=0, "Ilość Stan Początkowy M"=0,
"Ilość FZ"=SUM(IsNull(TrE_Ilosc,0)*CASE WHEN TrE_TypDokumentu=301 THEN
1 ELSE 0 END),
"Ilość FS"=SUM(IsNull(TrE_Ilosc,0)*CASE WHEN TrE_TypDokumentu=302 THEN
1 ELSE 0 END),
"Ilość PA"=SUM(IsNull(TrE_Ilosc,0)*CASE WHEN TrE_TypDokumentu=305 THEN
1 ELSE 0 END),
"Ilość PZ"=SUM( IsNull(TrE_Ilosc,0)*CASE WHEN TrE_TypDokumentu=307 THEN
1 ELSE 0 END),
"Ilość PKA"=SUM( IsNull(TrE_Ilosc,0)*CASE WHEN TrE_TypDokumentu=313
THEN 1 ELSE 0 END),
"Ilość PW"=SUM( IsNull(TrE_Ilosc,0)*CASE WHEN TrE_TypDokumentu IN
(310,303,317) THEN 1 ELSE 0 END),
"Ilość MM OL"= SUM( IsNull(TrE_Ilosc,0)*CASE WHEN TrE_TypDokumentu =
312 AND TrN_Rodzaj = 312010 THEN 1 ELSE 0 END),
"Ilość WZ"=SUM( IsNull(TrE_Ilosc,0)*CASE WHEN TrE_TypDokumentu=306 THEN
1 ELSE 0 END),
"Ilość WKA"=SUM( IsNull(TrE_Ilosc,0)*CASE WHEN TrE_TypDokumentu=314
THEN 1 ELSE 0 END),
"Ilość RW"=SUM( IsNull(TrE_Ilosc,0)*CASE WHEN TrE_TypDokumentu IN
(304,318) THEN 1 ELSE 0 END),
"Ilość MM LO"= SUM( IsNull(TrE_Ilosc,0)*CASE WHEN TrE_TypDokumentu =
312 AND TrN_Rodzaj = 312100 THEN 1 ELSE 0 END),
"Wartość Stan Początkowy H"=0, "Wartość Stan Początkowy M"=0,
"Wartość FZ"=SUM(IsNull(TrE_WartoscNetto,0)*CASE WHEN
TrE_TypDokumentu=301 THEN 1 ELSE 0 END),
"Wartość FS"=SUM(IsNull(TrE_WartoscNetto,0)*CASE WHEN
TrE_TypDokumentu=302 THEN 1 ELSE 0 END),
"Wartość PA"=SUM(IsNull(TrE_WartoscNetto,0)*CASE WHEN
TrE_TypDokumentu=305 THEN 1 ELSE 0 END),
"Wartość PZ"=SUM( IsNull(TrE_WartoscNetto,0)*CASE WHEN
TrE_TypDokumentu=307 THEN 1 ELSE 0 END),
"Wartość PKA"=SUM( IsNull(TrE_WartoscNetto,0)*CASE WHEN
TrE_TypDokumentu=313 THEN 1 ELSE 0 END),
"Wartość PW"=SUM( IsNull(TrE_WartoscNetto,0)*CASE WHEN TrE_TypDokumentu
IN (310,303,317) THEN 1 ELSE 0 END),
"Wartość MM OL"= SUM( IsNull(TrE_WartoscNetto,0)*CASE WHEN
TrE_TypDokumentu = 312 AND TrN_Rodzaj = 312010 THEN 1 ELSE 0 END),
"Wartość WZ"=SUM( IsNull(TrE_WartoscNetto,0)*CASE WHEN
TrE_TypDokumentu=306 THEN 1 ELSE 0 END),
"Wartość WKA"=SUM( IsNull(TrE_WartoscNetto,0)*CASE WHEN
TrE_TypDokumentu=314 THEN 1 ELSE 0 END),
"Wartość RW"=SUM( IsNull(TrE_WartoscNetto,0)*CASE WHEN TrE_TypDokumentu
IN (304,318) THEN 1 ELSE 0 END),
"Wartość MM LO"= SUM( IsNull(TrE_WartoscNetto,0)*CASE WHEN
TrE_TypDokumentu = 312 AND TrN_Rodzaj = 312100 THEN 1 ELSE 0 END),
"Ilość Stan Obecny"= (select sum(CDN.TwrZasoby.TwZ_Ilosc) from
cdn.TwrZasoby where CDN.Towary.Twr_TwrId = CDN.TwrZasoby.TwZ_TwrId),
"Ilość 2012"=(select twi_ilosc from cdn.TwrIlosci
where TwI_TwrId =CDN.Towary.Twr_TwrId and TwI_MagId = 1
and twi_data=(select top 1 TwI_Data from cdn.TwrIlosci where TwI_TwrId
= CDN.Towary.Twr_TwrId and TwI_MagId = 1 and twi_data
<=CONVERT(DATETIME,''' + CONVERT(VARCHAR,@DATA12,120) + ''',120) order
by twi_Data desc)),
"Ilość Stan Start"=(select twi_ilosc from cdn.TwrIlosci
where TwI_TwrId =CDN.Towary.Twr_TwrId and TwI_MagId = 1
and twi_data=(select top 1 TwI_Data from cdn.TwrIlosci where TwI_TwrId
= CDN.Towary.Twr_TwrId and TwI_MagId = 1 and twi_data
<=CONVERT(DATETIME,''' + CONVERT(VARCHAR,@DATAOD,120) + ''',120) order
by twi_Data desc)),
"Ilość Stan Stop"=(select twi_ilosc from cdn.TwrIlosci
where TwI_TwrId =CDN.Towary.Twr_TwrId and TwI_MagId = 1
and twi_data=(select top 1 TwI_Data from cdn.TwrIlosci where TwI_TwrId
= CDN.Towary.Twr_TwrId and TwI_MagId = 1 and twi_data
<=CONVERT(DATETIME,''' + CONVERT(VARCHAR,@DATADO,120) + ''',120) order
by twi_Data desc))
' + @kolumny +
' FROM CDN.Towary
LEFT OUTER JOIN cdn.TraElem ON TrE_TwrID=Twr_TwrID
LEFT OUTER JOIN cdn.TraNag ON TrN_TrNID=TrE_TrNID
LEFT OUTER JOIN cdn.Magazyny ON Mag_MagID=TrN_MagZrdID
LEFT OUTER JOIN cdn.Kategorie ON Kat_KatID=Twr_KatID
LEFT JOIN #tmpTwrGr Poz ON Twr_TwGGIDNumer = Poz.gidNumer
WHERE (TrN_Bufor<>-1 AND TrN_Korekta IN (0,1) OR TrN_TrNID IS NULL)
AND (((TrE_TypDokumentu IN (302,304,305,306,314,318) OR TrN_Rodzaj IN
(312100)
OR ((TrE_TypDokumentu IN (301,310,303,307,313,317) OR TrN_Rodzaj IN
(312010)) AND TrN_Bufor=0))
AND TrE_Aktywny<>0) OR TrE_TrEID IS NULL)
AND (TrN_DataOpe BETWEEN CONVERT(DATETIME,''' +
CONVERT(VARCHAR,@DATAOD,120) + ''',120) AND CONVERT(DATETIME,''' +
CONVERT(VARCHAR,@DATADO,120) + ''',120) OR TrE_TrEID IS NULL)
GROUP BY Twr_TwrID ' + @kolumny2 + '
UNION ALL
SELECT
DB_NAME() [Baza Firmowa],
MAX(Twr_Kod) [Produkt Kod],
25003 [Produkt Kod __PROCID__Towary__], Twr_twrId [Produkt Kod __ORGID__],
MAX(Twr_Nazwa) [Produkt Nazwa],
25003 [Produkt Nazwa __PROCID__], Twr_twrId [Produkt Nazwa __ORGID__],
MAX(CASE
WHEN Twr_Typ = 0 AND Twr_Produkt = 0 THEN ''Us³uga Prosta''
WHEN Twr_Typ = 1 AND Twr_Produkt = 0 THEN ''Towar Prosty''
WHEN Twr_Typ = 0 AND Twr_Produkt = 1 THEN ''Us³uga Z³o¿ona''
WHEN Twr_Typ = 1 AND Twr_Produkt = 1 THEN ''Towar Z³o¿ony''
ELSE ''(NIEOKREŒLONY)''
END) [Produkt Typ],
ISNULL(MAX(Kat_KodOgolny),''(NIEOKREŚLONA)'') [Produkt Kategoria
Ogólna], ISNULL(MAX(Kat_KodSzczegol),''(NIEOKREŚLONA)'') [Produkt
Kategoria Szczegółowa], MAX(Twr_JM) [Jednostka Miary],
"Ilość Stan Początkowy H"=SUM(IsNull(TrE_Ilosc,0)*CASE WHEN
TrE_TypDokumentu=301 THEN 1 WHEN TrE_TypDokumentu IN (302,305) THEN -1
ELSE 0 END),
"Ilość Stan Początkowy M"=SUM(IsNull(TrE_Ilosc,0)*CASE WHEN
TrE_TypDokumentu IN (310,303,307,313,317) THEN 1 WHEN TrE_TypDokumentu
IN (301,302,305) THEN 0 ELSE -1 END),
"Ilość FZ"=0, "Ilość FS"=0, "Ilość PA"=0, "Ilość PZ"=0, "Ilość PKA"=0,
"Ilość PW"=0, "Ilość MM OL"=0, "Ilość WZ"=0, "Ilość WKA"=0, "Ilość
RW"=0, "Ilość MM LO"=0,
"Wartość Stan Początkowy H"=SUM(IsNull(TrE_WartoscNetto,0)*CASE WHEN
TrE_TypDokumentu=301 THEN 1 WHEN TrE_TypDokumentu IN (302,305) THEN -1
ELSE 0 END),
"Wartość Stan Początkowy M"=SUM(IsNull(TrE_WartoscNetto,0)*CASE WHEN
TrE_TypDokumentu IN (310,303,307,313,317) THEN 1 WHEN TrE_TypDokumentu
IN (301,302,305) THEN 0 ELSE -1 END),
"Wartość FZ"=0, "Wartość FS"=0, "Wartość PA"=0, "Wartość PZ"=0,
"Wartość PKA"=0, "Wartość PW"=0, "Wartość MM OL"=0, "Wartość WZ"=0,
"Wartość WKA"=0, "Wartość RW"=0, "Wartość MM LO"=0,
"Ilość Stan Obecny"=0,
"Ilość 2012"=0,
"Ilość Stan Start"=0,
"Ilość Stan Stop"=0
' + @kolumny +
' FROM CDN.Towary
LEFT OUTER JOIN cdn.TraElem ON TrE_TwrID=Twr_TwrID
LEFT OUTER JOIN cdn.TraNag ON TrN_TrNID=TrE_TrNID
LEFT OUTER JOIN cdn.Magazyny ON Mag_MagID=TrN_MagZrdID
LEFT OUTER JOIN cdn.Kategorie ON Kat_KatID=Twr_KatID
LEFT JOIN #tmpTwrGr Poz ON Twr_TwGGIDNumer = Poz.gidNumer
WHERE (TrN_Bufor<>-1 AND TrN_Korekta IN (0,1) OR TrN_TrNID IS NULL)
AND (((TrE_TypDokumentu IN (302,304,305,306,314,318) OR TrN_Rodzaj IN
(312100)
OR ((TrE_TypDokumentu IN (301,310,303,307,313,317) OR TrN_Rodzaj IN
(312010)) AND TrN_Bufor=0))
AND TrE_Aktywny<>0) OR TrE_TrEID IS NULL)
AND (TrN_DataOpe < CONVERT(DATETIME,''' + CONVERT(VARCHAR,@DATAOD, 120)
+ ''',120) OR TrE_TrEID IS NULL)
GROUP BY Twr_TwrID' + @kolumny2
exec (@select)
DROP TABLE #tmpTwrGr
=============================================
--
Pozdrawiam.
Adam
Technical Details
Message-ID:
<pg2pop$u93$1$Adam@news.chmurka.net>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!news.chmurka.net!.POSTED.ent22.internetdsl.tpnet.pl!not-for-mailReferences:
<pg0f08$vgn$1$Adam@news.chmurka.net> <5b23e33e$0$589$65785112@news.neostrada.pl>Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!news.chmurka.net!.POSTED.ent22.internetdsl.tpnet.pl!not-for-mail From: Adam <a.g@poczta.onet.pl> Newsgroups: pl.comp.bazy-danych Subject: Re: Dziwne zmienne w MS-SQL Date: Sat, 16 Jun 2018 12:45:46 +0200 Organization: news.chmurka.net Message-ID: <pg2pop$u93$1$Adam@news.chmurka.net> References: <pg0f08$vgn$1$Adam@news.chmurka.net> <5b23e33e$0$589$65785112@news.neostrada.pl> NNTP-Posting-Host: ent22.internetdsl.tpnet.pl Mime-Version: 1.0 Injection-Date: Sat, 16 Jun 2018 10:45:45 +0000 (UTC) Injection-Info: news.chmurka.net; posting-account="Adam"; posting-host="ent22.internetdsl.tpnet.pl:83.15.205.22"; logging-data="31011"; mail-complaints-to="abuse-news.(at).chmurka.net" User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0 In-Reply-To: <5b23e33e$0$589$65785112@news.neostrada.pl> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit