Denne tråd er over 6 måneder gammel
Er du sikker på, at du har noget relevant at tilføje?
SQL Procedure array inputAf Ny på siden Axlon | 13-02-2024 13:06 | 1711 visninger | 14 svar, hop til seneste
Hej
Jeg er forholdsvis ny i SQL-programering, så bære lige over med mig.
Jeg har lavet en procedure til at finde/oprette en bruger i en tabel på en MS-SQL database, og som retunerer ID på brugeren.
EXEC @USER_ID = [Get_USER_ID] 'FirstName' , 'LastName'
Nu kunne jeg godt tænke mig at lave en anden procedure med flere navne input (array input), som kalder ovenstående procedure.
Altså noget ligende:
EXEC [USERS] [FirstNameA,LastNameA] , [FirstNameB,LastNameB] , [FirstNameC,LastNameC]
Hvordan dælen gør jeg det?
Syntes ikke rigtigt jeg har kunne finde noget brugbart eksempel på nettet. --
Aner ikke en skid om det, men det kunne være sjovt at spørge ChatGPT? :-) -- Mvh
Fc Junkies Det første spørgsmål du skal spørge dig selv er:
Hvad prøver jeg at opnå ved at sende array af brugere.
Normen er at den ydre kode looper og kalder ind til sql Stored Procedure (SP).
Du kan dog godt sende et array ind, men du bliver fanget af mange små detaljer fordi det er et hack.
Hvorfor er det et hack:
Et parameter kan vidst højst være 4/8k i længde
Du ved ikke hvor lange folks navne er og derfor skal ydersiden altså ligge og holde øje med om arrayet vil overskride makslængde.
Hvorfor vil man normalt afvige fra normen, der er stort set kun en årsag, man skal tilføje rigtigt mange linier og meget meget hurtigt. Og byte længden af data er kendt inden for rimelighedens grænser.
Kan man holde alle personerne inden for en variabel/sæt af variable kan man argumentere for at man kan få lokal transaction styring på "gratis", men det er kun nogle meget specifikke steder man faktisk ved dette med sikkerhed.
Du kan lave en komma/special tegn separeret værdi du sender med over, som dette:
firstnamea/lastnamea|firstnameb/lastnameb
Det kan du så først skære op i linier ved at søge efter første |
det giver dig dette som første linie
firstnamea/lastnamea
Det kan du så skære ud
col1 = firstnamea
col2 = lastnamea
etc
Du trunkere så den oprindelige værdi (evt lagt over i en arbejdsvariabel) lige bagved førs fundne |
firstnameb/lastnameb
Du kan nu ikke finde flere | og behandler derfor resten som sidste linie
Jeg har brugt dette trick 1 gang i min relativt lange karrier, tricket virker og det går virkeligt stærkt fordi man sparer turer frem og tilbage imellem sqlserver og klient/apiserver. Men det er en virkelig skidt løsning normalt.
Tilbage til første spørgsmål: hvad prøver du at opnå og dette er næsten med garanti den forkerte vej.
Held og lykke -- Det jeg ønsker, er at begrænse antal queries jeg sender afsted til SQL serveren.
Min [Get_USER_ID] procedyre var blot et forsimplet eksempel, og indgår i en større relations database.
Jeg har en resultat tabel med en del kolonner, hvor den ene kolonne er bruger [ID], som pejer på User_ID tabellen.
I dag har jeg en procedyre til at indsætte et resultat i min resultat tabel, og den procedyre kalder så min [Get_USER_ID] , for at få/oprette en bruger i min USER_ID tabel.
Det virker også helt fint.
Problemmet er blot at jeg har >10.000 resultater, og jeg derfor kommer til at sende lige så mange queries afsted.
-- Måske jeg skal skrive mine resulteter direkte ned i en "import tabel" og så kalde en procedyre som så henter data fra den tabel, og finder USER_IDs mm, og ligger det ud i de rigtige tabeler med relationer? -- Der er ingen direkte support for array input i SQL procedurer.
Typisk sender man noget ind og parser det om efterfølgende.
Enten som en string separeret af et specielt tegn såsom ',' eller '|' - og derefter kan man selv lave det om til en record af en art.
Se eventuelt: https://stackoverflow.com[...] -- #0
Sjovt nok sad jeg i foregaars og skulle goere noget lignende. Mit "Hack" var at sende en JSON string ind, og saa soerge for at der aldrig blev sendt mere end den varchar kunne haandtere. (Det drejede sig om et par raekker med meget lidt tekst af gangen).
Saa brugte jeg OPENJSON funktionen til at konvertere det til en tabel, og saa kunne jeg arbejde med dataene der fra. I mit tilfaelde lave en insert i en tabel.
Tjek: https://learn.microsoft.com[...]
Som #2 ogsaa er inden over at det lidt af en hack fordi det ikke er meningen og der er forskellige problemer der kan opstaa. I mit tilfaelde var alt mine data sanitized foerhen og jeg var 100% sikker paa det data der bliver sent over i JSON kan blive konverteret til de forventede vaerdier. Saa ja, det virkede og virker faktisk smukt lige nu.
Lad mig vide hvis du ikke kan faa det til at virke, saa send mig en PM. -- 2x ASUS STRIX 1070 OC, I7 AIO WaterCooled, 16GB RAM, Samsung 850 Evo, 500Gb, x34a 100HZ UWQHD 3440x1440 G-SYNC. K70 RGB Keyboard, M65 Pro RGB Mouse #3
Det er ikke altid lykken at begrænse queries/kald til serveren, når/hvis man ender med at overkomplicere sin kode, som det lyder lidt som om du er i gang med.
Man ender mange gange med noget der ikke er til at vedligeholde, endsige rette/udvide i.
Men, skal jeg komme med et input, så ville jeg nok gøre det som #6 omtaler.
Det er i hvert fald den metode jeg benyttede sidst jeg rodede med det.
(At jeg endte med at gå væk fra det igen, er en anden sag.) -- https://onsdagssnegl.dk[...]
"Held er noget, der indtræffer, når grundige forberedelser mødes med gunstig lejlighed" #7
Jeg er meget stor tilhænger af "keep it simple", men da jeg har over 4000 sæt data per testreport, så blev min overførelsestid per testreport på flere minuter, hvilket ikke er acceptabelt.
Jeg har ikke været opmærksom på begrænsningen med datastørelsen på procedyren, så den vej er nok også en blindgyde.
Jeg tror jeg vil forsøge mig med en dataimport tabel, hvori jeg kan overføre alle mine datasæt til, og så lave en procedyre der henter data fra den tabel, og som ligger data ud i de forskellige tabeler med relations indexer. -- #7 Nu har jeg pænt kigge på onsdagssnegl.dk på en onsdag men får desværre fejl:
Error 1033 Ray ID: 85546f4d9d806a63 • 2024-02-14 09:55:19 UTC Argo Tunnel error
Tænker det er sjovest at linke til noget der virker :) -- #9
Det får jeg da lige fikset.
Der er flyttet en del rundt med servere på det seneste, og kun det vigtigste er kommet på plads -- https://onsdagssnegl.dk[...]
"Held er noget, der indtræffer, når grundige forberedelser mødes med gunstig lejlighed" String parsing er sku noget knald. Jeg er ikke hellig, been there done that.
MEN
Hvorfor ikke lave x antal stored procedures med rigtige x antal parametre.
FlipHat1(params)
FlipHat5(5xparams)
FlipHat10(10xparams)
Osv.
Og bruge dem til at parse korrekt samt slippe for at fedte med string escapes også
Segmentering af input arrayet skal naturligvis afpasses til at passende/relevant stored procedure bruges optimalt -- Sidst redigeret 14-02-2024 21:30 #11
Jeg har netop lavet flere procedure med x antal parameter input.
En [resultat procedyre], som opretter et resultat (med en masse forskellige infomationer) i en resultat tabel, og retunerer index.
Dette index bruger jeg så i den næste procedyre, [numeric mesurement procedyre], som opretter en måling med en masse infomation, og hvori index for ovenstående resultat indgår.
Der kan godt være flere numeric mesurements for hvert resultat.
Jeg har også andre former for measurements, som alle pejer tilbage på min resultat tabel.
Jeg har så en testreport med 5000 forskellige resultater med 5000 tilhøende mesurements.
Dvs. jeg kalder min [resultat procedyre] og derefter min [numeric mesurement procedyre] 5000 gange.
Hver gang jeg kalder en procedyre, koster det ca. 25ms.
Dvs 2 x 5000 x 25ms = 250 sekunder, altså lidt over fire minuter. -- MSSQL understøtter ikke arrays... det gør Oracle til gengæld :P
men hvis du bare mener en tabel med flere specifikke brugere
så kan du gøre det sådan her:
SELECT * FROM USERS
WHERE (FirstName = 'Jens' AND LastName = 'Jensen')
OR (FirstName = 'Hans' AND LastName = 'Hansen')
OR (FirstName = 'Niels' AND LastName = 'Nielsen');
med mindre det er en gigantisk database, kan du ligeså godt bare "select *" (altså, alt data på users) da den alligevel skal ind og finde dem alle sammen, så kan du altid, i dit program, smide det ligegyldige data væk bagefter.
Der er altid adskillige måder at gøre tingene på. Det er både godt og skidt.
-- Sidst redigeret 15-02-2024 10:20 #13
Ja det er nemt nok at hente en tabel, men det var ikke det spørgsmålet gik på. --
Grundet øget spam aktivitet fra gæstebrugere, er det desværre ikke længere muligt, at oprette svar som gæst.
Hvis du ønsker at deltage i debatten, skal du oprette en brugerprofil.
Opret bruger | Login
|
Du skal være logget ind for at tilmelde dig nyhedsbrev.
Hvilken udbyder har du til internet? 424 personer har stemt - Mit energiselskab (Ewii f.eks) 11%
|