webForumDet fria alternativet

Hur få en utfil med alla artnr i samma post?

Databaser & SQL

5 svar · 610 visningar · startad av wazid

Medlem sedan maj 2001156 inlägg
Frågan#1

Hej

Jag vill skapa ett jobb som varje dag skapar en semikolonseparerad textfil från en orderdatabas i SQL (MS 2000).

I textfilen ska varje kund ha en rad.

Jag kan få fram informationen men då blir det 5 poster om en kund köpt 5 artiklar.
Men jag vill få en rad för kunden och i postiionen för Artnr ska alla 5 artikelnr så med ett kommatecken emellan.

SELECT 
dbo.OSBSTD1.UCORNO AS Ordernr, 
dbo.OSBSTD1.UCORDT AS Orderdatum, 
'""' AS Expr1, 
'""' AS Expr3, 
'""' AS Expr4, 
dbo.OSBSTD1.UCITNO AS Artnr,                     
'SV' AS Expr2, 
dbo.OSBSTD1.UCCUNO AS Kundnr, 
dbo.OSBSTD1.UCIVDT AS Datum, 
'Företaget AB' AS Expr5, 
'Gatuadress' AS Expr6,
'Postnr' AS Expr7, 
'Stad' AS Expr9, 
'Sverige' AS Expr10, 
1 AS Antalpersoner, 
dbo.OSBSTD1.UCCUNO AS Uniktpersonid, 
dbo.OCUSMA.OKYREF AS Fornamn, 
dbo.OCUSMA.OKYREF AS Efternamn, 
dbo.CEMAIL.CBEMAL AS epost, 
1 AS Formatspecifikation
FROM dbo.OSBSTD1 INNER JOIN
dbo.OCUSMA ON dbo.OSBSTD1.UCCUNO = dbo.OCUSMA.OKCUNO 
LEFT OUTER JOIN dbo.CEMAIL 
ON dbo.OCUSMA.OKCUNO = dbo.CEMAIL.CBEMKY
WHERE  (dbo.OSBSTD1.UCIVDT BETWEEN 20070101 AND 20070131)

Någon som har någon idé?

MvH

David

Medlem sedan sep. 2006867 inlägg
#2

En relationsdatabas tror jag inte kan skapa ett dynamiskt svar på det sättet du tänkt dig, i varje fall inte med en "enkel" SQL-fråga. Men om du kan/har rättigheter så går det alldeles utmärkt med en stored procedure, då kan du skapa Artnr och konkatenera bäst du vill och returnera en sträng med siffror och kommatecken i.

MVH

Medlem sedan maj 2001156 inlägg
#3

Hmmm

Inte så enkelt med andra ord.
Nu känner man sig lite dämpad....

//David

Medlem sedan sep. 2006867 inlägg
#4

Mjo, googlade lite och hittade den här artikeln http://www.databasejournal.com/features/msaccess/article.php/2247531

Förvisso för Access men han poängterar ändå att man måste skapa en funktion för att lösa det och det är nog en universell sanning för en RDBMS.

Medlem sedan maj 2001156 inlägg
#5

Perfekt. Vekar inte så svårt.
Har testat och jag kan skapa en stored procedure. Men mina programmeringskunskaper är inte så bra.

Följande har jag lagt in i den och så långt fungerar det.

CREATE PROCEDURE sp_test2
@startdatum VARCHAR(8),
@slutdatum VARCHAR(8)

AS
SELECT OSBSTD1.UCORNO AS Ordernr, dbo.OSBSTD1.UCORDT AS Orderdatum, '""' AS Expr1, '""' AS Expr3, '""' AS Expr4, dbo.OSBSTD1.UCITNO AS Artnr, 
                      'SV' AS Expr2, dbo.OSBSTD1.UCCUNO AS Kundnr, dbo.OSBSTD1.UCIVDT AS Datum, 'Foretaget AB' AS Firma, 'Gatuadress 1' AS Adress, 
                      '123 45' AS Postnr, 'Stad' AS Stad, 'Sverige' AS Land, 1 AS Antalpersoner, dbo.OSBSTD1.UCCUNO AS Uniktpersonid, 
                      dbo.OCUSMA.OKYREF AS Fornamn, dbo.OCUSMA.OKYREF AS Efternamn, dbo.CEMAIL.CBEMAL AS epost, 1 AS Formatspecifikation
FROM         dbo.OSBSTD1 INNER JOIN
                      dbo.OCUSMA ON dbo.OSBSTD1.UCCUNO = dbo.OCUSMA.OKCUNO LEFT OUTER JOIN
                      dbo.CEMAIL ON dbo.OCUSMA.OKCUNO = dbo.CEMAIL.CBEMKY
WHERE     (dbo.OSBSTD1.UCIVDT between @startdatum AND @slutdatum)

GO

Men jag skulle behöva göra den snurran som kontrollerar om Kundnr är detsamma som i föregående post och i så fall bygga upp en variabel med artikelnr så länge det är samma kundnr.
När det sedan blir ett nytt kundnr så skall en post skapas där variablen med artikeln skriv in i ett fält som kallas artikelnr.

Det är väl något sådant som koden gör i den accessfil du hittade?
Men hur skriver man det i en Stored Procedure?

Public Function FixTable() As Boolean
On Error Resume Next

Dim db As DAO.Database, rst As DAO.Recordset, sSQL As String
Dim strColumn1 As String, strColumn2 As String

Set db = CurrentDb()
Call RecreateTables(db)

Stop
sSQL = "SELECT Column1, Column2 FROM tblOriginal " _
       & "ORDER BY Column1, Column2 ASC"
Set rst = db.OpenRecordset(sSQL, dbOpenSnapshot)

If Not rst.BOF And Not rst.EOF Then
  rst.MoveFirst
  strColumn1 = rst!Column1
  strColumn2 = rst!Column2
  
  rst.MoveNext
  Do Until rst.EOF
    If strColumn1 = rst!Column1 Then
      strColumn2 = strColumn2 & ", " & rst!Column2
    Else
      sSQL = "INSERT INTO tblCopy (Column1, Column2)  " _
           & "VALUES('" & strColumn1 & "','" & strColumn2 & "')"
      db.Execute sSQL
      strColumn1 = rst!Column1
      strColumn2 = rst!Column2
    End If
    rst.MoveNext
  Loop
  
  ' Insert Last Record
  sSQL = "INSERT INTO tblCopy (Column1, Column2)  " _
       & "VALUES('" & strColumn1 & "','" & strColumn2 & "')"
  db.Execute sSQL
End If

Set rst = Nothing
Set db = Nothing

DoCmd.OpenForm "frmOutput"

End Function
Medlem sedan sep. 2006867 inlägg
#6

Oj, det blir ett låååångt svar på det och jag har inte MSSQL installerat just nu så jag vågar inte plita ner någon kod, men i stora drag handlar det om att skapa en temporär tabell i SP:n samt att öppna en CURSOR som stegar sig igenom resultatet från din ursprungliga fråga. I varje loop i cursorn så lagrar du undan Artnr för varje kund och innan du byter kund så lagrar du en rad i temp-tabellen med alla värden du vill skicka med inklusive din nya Artnr_med_flera_värden.

Jag skulle gärna hjälpa dig med hela SPn inklusive cursors och jag satt faktiskt i 30 minuter och skrev på kod innan jag insåg att jag inte kunde testköra och då gav jag upp :) Men det finns ju fler snälla wF:are och det är egentligen inte så svårt att skriva om din VB-loop ovan till SQL, bara man kan syntaxen. Sök på sql + cursor :)

MVH

265 ms totalt · 4 externa anrop · v20260731065814-full.6fe65c25
123 ms — deklarationer (db)
0 ms — hämta statistik (cache)
136 ms — hämta tråd, inlägg och bilagor (db)
126 ms — ändringar (db)