Avatar billede osborne Nybegynder
13. marts 2007 - 15:25 Der er 21 kommentarer og
1 løsning

Brug af et udtræk ny select?

Jeg har søgt her på eksperten men ikke lige fundet en løsning (muligvis har jeg ikke ledt grundigt nok), men her mit spørgsmål.

Jeg har behov for at bruge resultatkolonnen fra et udtræk som del af navnet på en anden tabel ... mere konkret her jeg pt. skrevet to SQL sætninger der hver for sig virker fint:

SQL sætning 1 (udtrækker en liste over navnene på mine databaser):

select name from master.dbo.sysdatabases



SQL sætning 2 (udtrækker en værdi fra én af mine databaser som hedder user_tkv_labj_db):

select max(hs_change_date) as senest_rørt from user_tkv_labj_db.td.history


Udfordringen er så at jeg gerne vil lægge disse SQL sætning 1 og 2 sammen, således at der i SQL sætning 2 bruges værdierne af navn fra SQL sætning 1 istedet for user_tkv_labj_db. Nogen der kan hjælpe mig med en SQL sætning der kan give mig et sådant udtræk?
Avatar billede dr_chaos Nybegynder
13. marts 2007 - 15:30 #1
Måske noget i denne stil:
select name, max(hs_change_date) from master.dbo.sysdatabases t1
JOIN user_tkv_labj_db.td.history t2 ON t2.name= t1.name
GROUP BY name
Kommer lige an på navne i user_tkv_labj_db.td.history
Avatar billede dr_chaos Nybegynder
13. marts 2007 - 16:24 #2
Eller skal det være noget mere dynamisk sql ?
Avatar billede osborne Nybegynder
13. marts 2007 - 19:00 #3
Tak for dit svar, men jeg har ikke forklaret det godt nok.

Det er sådan at navnet user_tkv_labj_db ikke indeholder nogen name kolonne .. Faktisk skal user_tkv_labj_db slet ikke bruges men istedet alle navnene fra første udtræk en efter en istedet for der hvor der står user_tkv_labj_db.

Jeg kunne forestille mig noget i stil med en variabel der indeholder name fra første sql og så løber igennem og propper dette @n på den anden SQL .. måske som:

select max(hs_change_date) as senest_rørt from @n.td.history

Er jeg på rette spor .. eller kan det laves rent i SQL? Og kan jeg få resultatet ud i en stor resultattabel? (i dette tilfælde kan jeg sidde jeg på selve serveren og bruge SQL Server Enterprise manager istedet for applikationens egen SQL fortolker)
Avatar billede osborne Nybegynder
13. marts 2007 - 19:08 #4
.. hov jeg glemte at skrive noget løkke rundt om den angivne sql. Men hvordan opsamler jeg resultatet i et samlet udtræk? Kan man det
Avatar billede dr_chaos Nybegynder
13. marts 2007 - 19:28 #5
Måske noget i denne stil ?
CREATE TABLE #temp (
table varchar(255),
hs_change_Date datetime )

declare @minname varchar(255), @maxname varchar(255),@sql varchar(8000)
select @minname=min(name), @maxname= max(name) from master.dbo.sysdatabases
WHILE @minname<=@maxname
BEGIN

SET @sql = 'SELECT '+@minname+',max(hs_change_date)  FROM '+@minname
INSERT INTO #temp
EXEC( @sql)

select @minname=min(name) from master.dbo.sysdatabases WHERE name>@minname
END

SELECT * FROM #temp
drop table #temp
Avatar billede osborne Nybegynder
13. marts 2007 - 21:23 #6
Hvor er du bare god ..

Af en eller anden grund kan jeg ikke få lov til at logge på vores server her til aften så jeg kan ikke lige prøve det af, men vil gøre det så hurtigt som muligt. En ting der undrer mig er sætningen:

SET @sql = 'SELECT '+@minname+',max(hs_change_date)  FROM '+@minname

Så vidt jeg kan se ud fra din kode vil den lave sætninger i stil med:
SELECT user_tkv_labj_db, max(hs_change_date) FROM user_tkv_labj_db

Det forstår jeg ikke helt? Jeg forestillede mig noget med en tabel der listede databasenavne og datoer i en liste i stil med:

default_empty_db      12-11-2006
demo_best_practice_db 03-01-2007
user_tkv_labj_db      25-04-2006
...

Men det er måske også det som din kode vil give?
Avatar billede osborne Nybegynder
13. marts 2007 - 21:25 #7
Det jeg mener er at jeg ikke forstå at du efter 'SELECT ' anvender @minname.

Jeg er godt med at på den næste select tager den næste i rækken, og at du til sidst selecter hele den opbyggede #temp tabel. Det er rigtig smart.
Avatar billede osborne Nybegynder
13. marts 2007 - 21:34 #8
Jeg ville også have gættet på at der i den at der i din 'SELECT ' skulle udtrækkes fra history tabellen:

SET @sql = 'SELECT max(hs_change_date) FROM '+@minname+'.td.history'

Eller sådan noget lignende. Men jeg mangler så lige at få listet selve databasenavnet i listen. Er det korrekt?
Avatar billede dr_chaos Nybegynder
14. marts 2007 - 14:50 #9
Ja det er rigtigt prøv med:
SET @sql = 'SELECT '+@minname+',max(hs_change_date)  FROM '+@minname+'.td.history'
INSERT INTO #temp
EXEC( @sql)
Avatar billede osborne Nybegynder
14. marts 2007 - 23:03 #10
Ok .. jeg vil prøve dette asap og vende tilbage. Tak for hjælpen indtil videre, det er bare skønt! (det er lige før jeg drømmer om SQL om natten nu :-)
Avatar billede dr_chaos Nybegynder
15. marts 2007 - 07:25 #11
hehe personligt kan jeg godt finde bedre ting at drømme om når jeg sover :)
Avatar billede osborne Nybegynder
15. marts 2007 - 12:58 #12
Jeg har nu prøvet følgende på serveren (den kunne ikke lide en parameter til create table som hed table så jeg har kaldt det table_name.


CREATE TABLE #temp (table_name varchar(255), hs_change_Date datetime)

declare @minname varchar(255), @maxname varchar(255), @sql varchar(8000)
select @minname=min(name), @maxname=max(name) from master.dbo.sysdatabases

WHILE @minname<=@maxname
BEGIN
SET @sql = 'SELECT '+@minname+',max(hs_change_date)  FROM '+@minname+'.td.history'
INSERT INTO #temp
EXEC( @sql)
EXEC( @sql)
select @minname=min(name) from master.dbo.sysdatabases WHERE name>@minname
END

SELECT * FROM #temp
drop table #temp


Og jeg får en række fejlmeddelser tilbage:

Server: Msg 208, Level 16, State 1, Line 1
Invalid object name 'master.td.history'.
Server: Msg 208, Level 16, State 1, Line 1
Invalid object name 'master.td.history'.
Server: Msg 208, Level 16, State 1, Line 1
Invalid object name 'model.td.history'.
Server: Msg 208, Level 16, State 1, Line 1
Invalid object name 'model.td.history'.
Server: Msg 208, Level 16, State 1, Line 1
Invalid object name 'msdb.td.history'.
Server: Msg 208, Level 16, State 1, Line 1
Invalid object name 'msdb.td.history'.

Og det er jo selvfølgelig fordi jeg ikke tænkte på at det kun er nogle af databaserne der her en history tabel (det har alle standerd SQL server tabellerne ikke). Spekulerer nu på hvordan jeg kan angive det .. men måske noget med at tilføje WHERE name LIKE 'user_' (eller sådan noget lignende for at angive at basenavnene starter på noget bestemt).

Men jeg får også en række andre fejl:
Invalid column name 'user_best_practice'.
Server: Msg 207, Level 16, State 3, Line 1
Invalid column name 'user_best_practice'.
Server: Msg 207, Level 16, State 3, Line 1
..
osv.

Det kan jeg ikke lige gennemskue hvad skyldes .. kan det være pga. den der SELECT der bruger @minname?
Avatar billede osborne Nybegynder
15. marts 2007 - 13:02 #13
Fordi så vidt jeg forstår vil:
SET @sql = 'SELECT '+@minname+',max(hs_change_date)  FROM '+@minname+'.td.history'
INSERT INTO #temp

Vil den bygge sql sætninger i stil med SELECT user_best_practice, max(hs_change_name) FROM user_best_practice.td.history

Og det vil jo gå galt ikke?
Avatar billede osborne Nybegynder
23. marts 2007 - 23:24 #14
I går fik jeg så endelig bakset lidt med dette igen. Hvis jeg udelader første felt i den temporære tabel så virker det faktisk !!! dvs. noget i stil med følgende prøvede jeg på serveren:


CREATE TABLE #temp (hs_change_Date datetime)

declare @minname varchar(255), @maxname varchar(255), @sql varchar(8000)
select @minname=min(name), @maxname=max(name) from master.dbo.sysdatabases where name like 'prod_%'

WHILE @minname<=@maxname
BEGIN
SET @sql = 'SELECT max(hs_change_date)  FROM '+@minname+'.td.history'
INSERT INTO #temp
EXEC( @sql)
EXEC( @sql)
select @minname=min(name) from master.dbo.sysdatabases WHERE name>@minname and name like 'prod_%'
END

SELECT * FROM #temp
drop table #temp


Og det er jo udmærket at få listen over datoer på den måde. Men jeg kan stadig ikke greje hvordan man i SQL angiver at man vil se en kontret værdi som resultat i en kolonne (i dette eksempel værdien af @minname) .. dvs. angive en sådan konkret værdi istedet for et kolonnenavn.

Nogen der ved det?
Avatar billede dr_chaos Nybegynder
25. marts 2007 - 16:51 #15
Undskyld jeg ikke lige har været opmærksom på din post.
Jeg har haft lidt meget arbejde.
Kan du ikke uddybe hvad du mener med konkret værdi ?
Avatar billede osborne Nybegynder
25. marts 2007 - 17:17 #16
Hej dr_chaos .. jeg ville blot sige at ovenstående virker perfekt (dvs. hvor jeg har fjernet table_name varchar(255) fra CREATE TABLE linien og tilsværende kun undtrækker

SET @sql = 'SELECT max(hs_change_date) FROM ..

istedet for

SET @sql = 'SELECT '+@minname+',max(hs_change_date)  FROM ..

Det der så vidt jeg kan se er problemet er at @minname indeholder en konkret værdi dvs. navnet på en database og ikke som et kolonnenavn som SELECT vil forvente. Det jeg så spørger om er hvordan (eller om man i det hele taget kan) få værdien af @minname ind i første kolonne af den temporære tabel, når det jo ikke reelt set er et udtræk men blot en angivelse af en værdi.

Forstår du hvad jeg mener?
Avatar billede osborne Nybegynder
25. marts 2007 - 17:24 #17
Som workaround laver jeg pt. to SQL. Den første som giver mig listen over navne:
select name from master.dbo.sysdatabases where name like 'prod_%
(dette copy paster jeg så over i et excel regneark)

Dernæst laver jeg ovenstående løkke byggende på dit forslag men kun med datoer.
(dette copy paster jeg så over i en anden kolonne i regnearket)

På den måde får jeg et regneark med to kolonner. Men ville være frækt (og mere flexibelt) hvis det kunne klares fra SQL direkte at få de to kolonner dannet.
Avatar billede dr_chaos Nybegynder
26. marts 2007 - 12:08 #18
Virker det med:
SET @sql = 'SELECT '''+@minname+''', max(hs_change_date)  FROM '+@minname+'.td.history'
Avatar billede osborne Nybegynder
26. marts 2007 - 17:54 #19
Det må jeg prøve (med de der dobbelte gåseøjne).. Vender tilbage.
Avatar billede dr_chaos Nybegynder
26. marts 2007 - 20:18 #20
Ok
Du kan altid prøve med
print @sql
For at se om den sql du har lavet er god nok.
Avatar billede osborne Nybegynder
01. april 2007 - 13:51 #21
Ved du hvad dr_chaos .. DET VIRKER med de extra 'plinger', troede ellers jeg havde prøvet det hele. Tusind tak for din hjælp og udholdenhed! Tak også for tippet med print.

(post et svar så jeg kan give dig point)
Avatar billede dr_chaos Nybegynder
02. april 2007 - 19:08 #22
perfekt.
svar :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester