Avatar billede prince10 Nybegynder
18. april 2005 - 10:38 Der er 10 kommentarer og
1 løsning

Dynamisk sql-string

Er ved at lave en .net løsning (VB) på en MSsql-database.

Jeg har to tabeller:
tbl_komponentmaster og tbl_komponentmasterSetting. I tbl_komponentmaster har jeg komponenter, med tilhørende categoriID. Ikke alle felter skal udfyldes/vises for de enkelte komponenter. Styringen af hvilke felter, der skal vises/udfyldes vil jeg gemme i tbl_komponentmasterSetting (UniqueID, categoryID, CategoryName + alle felter fra tbl_komponentmaster oprettet som bit-felter.
En række i tbl_komponentmasterSetting ser derfor f.eks. sådan ud:

UniqueID  1
categoryID 7
CategoryName bolte
length 1 (checked/vises)
pressure 0 (unchecked/vises ikke)
osv...
Jeg vil så lave en dynamisk sql-streng, hvor jeg henter alle felter som er = 1 (- altså alle felter der skal vises)
Denne sql-streng vil jeg så overføre som parameter til en stored procedure, som så returnerer resultatet til applikationen.
Det skulle gerne ende med at jeg kun får vist de felter fra tbl_komponentmaster som er = 1 i tbl_komponentmasterSettings.

Hvordan laver jeg lige denne selectstreng?
Avatar billede dbangx Nybegynder
18. april 2005 - 13:44 #1
damn... har siddet i en time og forsøg at ave noget der virkede, men ude held... Havde forsøgt at erklære en variabel af tyen table og for hver test af bits så kalde ALTER TABLE og update med værdien der skulle ud, men man kan åbenbart ikke lave alter table på en @variabel. Jeg vil foreslå dig at du gør en af to ting:

1:
dropper tbl_komponentmasterSetting og istedet lader være med at udfylde de columns i tbl_komponentmaster, der ikke skal med for den enkelte record.

2: gør tbl_komponentmasterSetting lodret i stedet fo vandret. eks.

komponentmaster_id : 5
row_name: pressure
vises: 0

komponentmaster_id : 5
row_name: length
vises: 1

for så kan du for hver af disse:
SELECT * FROM tbl_komponentmasterSetting where komponentmaster_id = 5

få fat i den row i tbl_komponentmaster du vil have :-)
Avatar billede prince10 Nybegynder
18. april 2005 - 15:12 #2
det forstår jeg ikke rigtigt...
Jeg laver et kald til tbl_komponentmaster

Kald 1:

select <kolonner> from tbl_komponentmaster
where CategoryID = 7

<kolonner> skal vælges som en selection ud fra tbl_komponentmasterSetting
(I denne tabel har jeg alle feltdefinitioner fra tbl_komponentmaster + id(auto) + categoryID (som er hentet/Oprettet ud fra en kategoritabel)

Kald 2:
select * from tbl_komponentmasterSetting
where categoryID = 7
hvor jeg overfører et categoryID, og får rækken med dette id.
dette vil f.eks. give:
id 555
CategoryID 7
partn_no 1 (bit)
name 1 (bit)
length 1 (bit)
width 0 (bit)
Rækken hvis kolonner så har værdien 1 (felter som skal vises) skal så laves som en parameter der skal indsættes i første sql-sætning <kolonner> (Kald 1)
Kan de overhovedet lade sig gøre...
Avatar billede dbangx Nybegynder
18. april 2005 - 15:22 #3
Jeg kan ikke overskue en løsning i transact sql. Hvis det skal foregå på den måde, så er det måske bedre at lave noget kode i vb, der kan tage sig af det
Avatar billede dbangx Nybegynder
18. april 2005 - 15:25 #4
eksempel:

kald fra vb:
"SELECT * FROM ...setting"
opbyg en streng på formen: Streng = "column1,column12,column3... osv." selvfølgelig skal de kun med hvis bitten er 1.

så fyrer du denne af:

"SELECT " & Strebg & "FROM ...master WHERE ..."
Avatar billede prince10 Nybegynder
19. april 2005 - 11:01 #5
Nogen der har et eksempel på hvordan jeg får lavet strengen, der giver col1,col2,colx.... hvor værdien i rækken er 1 (sand)
Avatar billede dbangx Nybegynder
19. april 2005 - 11:49 #6
jeg er ikke særlig hård i vb, men det her giver dig strengen:

Dim cmd As OleDb.OleDbCommand
        Dim r As OleDb.OleDbDataReader
        Dim s As String
        sqlconn.Open()


        cmd = sqlconn.CreateCommand()

        cmd.CommandText = "SELECT * FROM setting WHERE id = 1;"
        r = cmd.ExecuteReader()
        s = ""
        If r.Read Then
            If (r.GetBoolean(1)) Then s = s & r.GetName(1) & ","
            If (r.GetBoolean(2)) Then s = s & r.GetName(2) & ","
            If (r.GetBoolean(2)) Then s = s & r.GetName(3) & ","
            If (r.GetBoolean(2)) Then s = s & r.GetName(4) & ","
            s = s.Remove(s.Length - 1, 1)

        TextBox1.Text = s
        End If

jeg har en tabel der hedder setting med id (int),col1, col2, col3, col4 (bit)
Avatar billede prince10 Nybegynder
20. april 2005 - 11:19 #7
Ok - det virker fint nok - Hvordan får jeg så overført s til min stored proc.
Har prøvet med:
CREATE PROCEDURE dbo.SP_TestMaster
@inParentID int,
@aktiv int,
@selectstring text
AS
    SELECT @selectstring
    FROM        tbl_component_master
    WHERE    (tbl_component_master.Active = @aktiv) AND (tbl_component_master.Category_discriminator = @inParentID)
GO
Men jeg får ikke noget fornuftigt tilbage...
Avatar billede dbangx Nybegynder
20. april 2005 - 14:51 #8
hmmm... er der nogen grund til at have det i en procedure?
Du kunne jo bare kalde en ny select sætning efter du har fundet s:

...
s = s.Remove(s.Length - 1, 1)

cmd.CommandText = "SELECT "&s&" FROM tbl_component_master WHERE Active=?? AND Category_discriminator=??"
r = cmd.ExecuteReader()
while r.read()
...
Avatar billede prince10 Nybegynder
26. april 2005 - 00:49 #9
Takker det virker
Avatar billede dbangx Nybegynder
26. april 2005 - 07:40 #10
selv tak for point :-/
Avatar billede dbangx Nybegynder
27. april 2005 - 09:42 #11
synes du det er helt fair selv at tage alle pointene?
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