Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi MS-SQL Procedure & Resultset??? (https://www.delphipraxis.net/33486-ms-sql-procedure-resultset.html)

Kedariodakon 8. Nov 2004 08:55


MS-SQL Procedure & Resultset???
 
So follgendes Problem:

Ich habe eine Procedure, welche ein paar Berechnungen durchführt und mir dann eine von 2 Temp Tabellen zurückgiebt...
Diese wurden errechnet und werden nach dem select gleich wieder gelöscht...
Entweder "select * from Temp_Output" oder "select * from Temp_Error" falls ein Fehler auftratt...

So in meinem Programm arbeite ich eigendlich bis jetzt nu mit der ADOConnection, nem ADODataset und einer ADOCommand Komponente, da ich bis jetzt nur Recordsets auswerten mußte...

damit ich aber die Tabelle von der Procedure anschaun kann, bräuchte ich aber noch eine DataSource und eine ADOQuery bzw. ADOTable...

Kann ich irgendwie die Procedure so umschreiben, dass ich meine Ergebnisstabelle als Recordsets zurückbekomm?
Dann bräucht ich auch nichts mehr ändern in meinem Programm...


ich hoff es hat wer Rat :)

Bye

Leuselator 8. Nov 2004 09:05

Re: MS-SQL Procedure & Resultset???
 
mach einfach als letztes statement ein Select auf deine tmp-tabelle und Du erhältst ein Recordset zurück...
Gruß

Jelly 8. Nov 2004 09:08

Re: MS-SQL Procedure & Resultset???
 
In MSSQL kannst du deine SP nach folgender Syntax aufbauen:
SQL-Code:
create procedure Text
as
Select * from Temp
GO
In Delphi rufst du die SP mittels ExecSQL auf.

Gruß

Kedariodakon 8. Nov 2004 09:25

Re: MS-SQL Procedure & Resultset???
 
Zitat:

Zitat von Leuselator
mach einfach als letztes statement ein Select auf deine tmp-tabelle und Du erhältst ein Recordset zurück...
Gruß

Wie als letztes?
das sieht ATM so aus (bzw. so ähnlich :) )

Code:
...
If @ERROR = 1
Begin
  Select * From [Temp_ERROR]
End Else Begin
  Select * From [Temp_Output]
End
DROP TABLE [Temp_ERROR]
DROP TABLE [Temp_Output]
Das in Klammern sieht ein bisle anders aus...

Jelly 8. Nov 2004 10:15

Re: MS-SQL Procedure & Resultset???
 
Also nur noch so am Rande, solltest du im Grund wirklich temporäre Tabellen in deiner SP benutzen (#TempTabelle). Denk immer dran daß mehrere Benutzer gleichzeitig die SP aufrufen können, und sich somit deine Eintragungen in der Temp Tabelle überschneiden können.

Kedariodakon 8. Nov 2004 12:08

Re: MS-SQL Procedure & Resultset???
 
öhm das ist wahr ^^
So hab ich das noch nicht gesehen :)
Bin grad neu eingestiegen in der datenbank sache...

Wie erstelle ich so eine #Temptable?

Jelly 8. Nov 2004 13:13

Re: MS-SQL Procedure & Resultset???
 
Zitat:

Zitat von Kedariodakon
Wie erstelle ich so eine #Temptable?

Na rate mal :zwinker:
SQL-Code:
create table #temp ....

Kedariodakon 8. Nov 2004 13:40

Re: MS-SQL Procedure & Resultset???
 
also nur ein # vor dem Tabellennamen?
Und die wird dann auch zerstört zum schluss? Brauch ich mich nicht drum zu kümmern?

BYE

Jelly 8. Nov 2004 13:58

Re: MS-SQL Procedure & Resultset???
 
Zitat:

Zitat von Kedariodakon
Und die wird dann auch zerstört zum schluss?

Da bin ich mir jetzt ehrlich gesagt nicht sicher. Ich glaube die wird zerstört sobald du deine Transaction abschliesst. Rufst du aber 2 mal die SP innerhalb der gleichen TA auf, bleibt sie glaube ich erhalten.

Gruß,
Tom

Leuselator 8. Nov 2004 15:51

Re: MS-SQL Procedure & Resultset???
 
So, wie Du es in Deinem 2. Post gezeigt hast, sollte es Dir ein Recordset zurückliefern. Wenn Du mit temporären Tabellen in Multi-Userumgebungen arbeitest, solltest Du Dir eine Routine schreiben, die eine eindeutig benamste Tabelle erzeugt. somit ist gewährleistet, dass Du immer allein (aus Sicht der SP) auf der Tabelle rumwerkelst. Allerdings mußt Du dann auf dynamic SQL zurückgreifen. Wenn Dir das neu ist, dann auch dazu ein kleines Beispiel. Viel Spass!
Beispiel:
SQL-Code:
-- erzeugt eindeutigen Tabellennamen
CREATE FUNCTION GetTmpTableName( @Tabelle     sysname)
RETURNS varchar(2000)
AS
BEGIN
  DECLARE @TmpTable    varchar(2000)        OUTPUT
        , @i        int

  SET @i = 0
  SET @TmpTable = '##Tmp_'+@Tabelle
  WHILE object_id('tempdb..'+@TmpTable, 'U') is not null BEGIN
    SET @i = @i+1
    SET @TmpTable = '##Tmp_'+@Tabelle+convert(varchar,@i)
  END
  RETURN (@TmpTable)
END

-- DemoSP für Dynamic SQL
CREATE PROCEDURE DoSomething
AS
BEGIN
  DECLARE @SQL        nvarchar(4000) -- Statements für dynSQL
        , @PARA       nvarchar(4000) -- Variablen für dynSQL
        , @TMP_TABELLE varchar(255)  -- Temporäre Tabelle
        , @DerCursor  Cursor        -- dynamischer Cursor
        , @DeineFeldEinsVariable int -- irgendwas halt

  -- Aufruf der obigen Funktion, um eindeutigen Tabellennamen zu erhalten
  SET @TMP_TABELLE = GetTmpTableName('MeineTmpTabelle')
 
  -- Statement, um diese Tabelle zu erzeugen und mit Werten zu füllen
  SET @SQL = 'INSERT INTO '+@TMP_TABELLE+' SELECT FeldEins,* FROM BlaBla'
  -- ausführen
  EXEC @SQL

  --Statement, um einen dynamischen Cursor für diese Tabelle anzulegen
  SET @SQL = 'SET @DerCursor = CURSOR FOR
              SELECT FeldEins
              FROM '+ @TMP_TABELLE+ '; Open @DerCursor'
  --Parameter für aufruf von sp_executesql erzeugen
  SET @PARA = '@DerCursor CURSOR OUTPUT'

  -- dynSQL ausführen
  EXEC sp_executesql @SQL, @PARA, @DerCursor

  -- mit dem dynamischen Cursor arbeiten
  FETCH NEXT FROM @DerCursor into @DeineFeldEinsVariable
  WHILE @@FETCH_STATUS = 0 BEGIN
    -- Mach was
    FETCH NEXT FROM @DerCursor into @DeineFeldEinsVariable
  END
  CLOSE @DerCursor
  DEALLOCATE @DerCursor

  -- einfache Abfrage auf die dyn. erzeugte temp. Tabelle
  SET @SQL = 'SELECT * FROM '@TMP_TABELLE'
  EXEC @SQL

  -- Tabelle löschen
  SET @SQL = 'DROP TABLE '+@TMP_TABELLE
  EXEC @SQL
END
Gruß

Kedariodakon 8. Nov 2004 16:01

Re: MS-SQL Procedure & Resultset???
 
Also sind diese Temp-Tabellen nicht einem bestimmten Benutzer zugeordnet und ich muß mich wieder um alles kümmern?

Warum dann #Temp tabellen nehmen stadt normale?


Bye

Robert_G 8. Nov 2004 16:10

Re: MS-SQL Procedure & Resultset???
 
Weil sie nur im Cache gehalten werden und dadurch massiv schneller erstellt, zugegriffen und zerstört werden könne. "Richtige" Tabellen dafür zu nehmen wäre doch totaler Schwachfug. ;)

btw: temp. Tabelle sind ein großer Vorteil vom SQL Svr gegenüber Oracle (die dortigen Temporär - Spaces sind nicht direkt im Speicher. Sie ähneln eher Tabeleln, die nicht dauerhaft gespeichert werden können.)

Leuselator 8. Nov 2004 16:11

Re: MS-SQL Procedure & Resultset???
 
Wenn verschiedene Benutzer die SP aufrufen, hast Du mit lokalen (ein # vor dem Namen - global 2 ## vor dem Namen) keine Last. Schwierig wird es, wenn die einzelnen Benutzer unterprivilegiert im DB-Zugriff sein sollen und nur die SP's in einem privilegierten User-Kontext laufen sollen (was Sinn macht), da dann alle User auf DB-Seite als ein Benutzer ankommen - daher mein Vorschlag. Für eine schnelle Abfrage aus dem Userkontext heraus ist "#TabellenName" ok.
Gruß

Kedariodakon 9. Nov 2004 08:35

Re: MS-SQL Procedure & Recordset???
 
Ok nun konnte ich dank eurer hilfe meine Procedure Verbessern, bzw. bugfixen! :thumb:

Aber die Frage mit dem Recordset bleibt weiterhin!

Ich habe mal ein bischen getestet gestern Abend und bin zu folgendem Result gekommen :angel2:

Code:
CREATE PROCEDURE Test1 AS
BEGIN
  CREATE TABLE #TEMP ( Output varchar( 10 ) )
  SELECT * FROM #TEMP
END
Diese Procedure gibt mir die leere Tabelle #Temp zurück UND auch als Recordset!!!

Diese Procedure:
Code:
CREATE PROCEDURE Test2 AS
BEGIN
  CREATE TABLE #TEMP ( Output varchar( 10 ) )
  INSERT INTO #TEMP ( Output ) VALUES ( '123 Test' )
  SELECT * FROM #TEMP
END
ist ein klein wenig anders!
1. Sie heißt ein kleinwenig anders :zwinker:
2. Ich tu was in die Tabelle, denn eine leere Tabelle bringt mir ja nichts! :wink:

Aber schon gibt ein Fehler bei ADO und zwar, dass das Recordset net geöffnet wär...
Und ich glaub nicht so wirklich das das an dem Namen liegt, das hab ich durch Tests ausschließen können... :coder:

Aber das kuriose bei der Sache ist, ich kann auch in eine Tabelle was reintun, die ich gar nicht als Result haben will, schon bekomm ich kein Recordset und kann mir die Daten nur per Query hollen...

Was mach ich den falsch? benutz ich insert falsch?

BYE

Kedariodakon 9. Nov 2004 14:30

Re: MS-SQL Procedure & Resultset???
 
HILFE :wall:

Leuselator 9. Nov 2004 14:51

Re: MS-SQL Procedure & Resultset???
 
zeig mal Delphi-Code...

Kedariodakon 9. Nov 2004 15:34

Re: MS-SQL Procedure & Resultset???
 
Was willst du da mit delphi code?

Aber bitte...
Delphi-Quellcode:
aTADODataSet.Recordset := aTADOCommand.Execute;
So alle Unklarheiten beseitigt? :zwinker:

Oder willst du auch noch wissen, wie der CommandText aussieht?
Aber wie gesagt, Test1 geht Test2 nicht...


Bye

Kedariodakon 10. Nov 2004 16:34

Re: MS-SQL Procedure & Resultset???
 
Ich suche immernoch eine Antwort -/ Lösung :|


Bye

shmia 10. Nov 2004 16:50

Re: MS-SQL Procedure & Resultset???
 
Hier meine Testprocedure:
SQL-Code:
CREATE PROCEDURE Test2 ( @ParameterQ varchar(20)) AS
BEGIN
  CREATE TABLE #TEMP99( Output varchar( 100 ) )
  INSERT INTO #TEMP99( Output ) VALUES ( '123 Test' )
  INSERT INTO #TEMP99( Output ) VALUES ( 'Hey, ist doch alles Oaki Doaki !!!' )
  INSERT INTO #TEMP99( Output ) VALUES ( @ParameterQ)
  SELECT * FROM #TEMP99 
END
Hier die Delphi-Seite (ich verwende TADOStoredProc):
Delphi-Quellcode:
   ADOStoredProc1.Active := False;
   ADOStoredProc1.ProcedureName := 'Test2';
   ADOStoredProc1.Parameters.Refresh;
   ADOStoredProc1.Parameters.ParamValues['ParameterQ'] := 'Delphi-Praxis';
   ADOStoredProc1.Active := True;
Datasource mit ADOStoredProc1 verbinden; diese mit einem DBGrid; fertig. :bounce2:

Kedariodakon 11. Nov 2004 08:44

Re: MS-SQL Procedure & Resultset???
 
Zitat:

Zitat von shmia
Hier meine Testprocedure:
SQL-Code:
CREATE PROCEDURE Test2 ( @ParameterQ varchar(20)) AS
BEGIN
  CREATE TABLE #TEMP99( Output varchar( 100 ) )
  INSERT INTO #TEMP99( Output ) VALUES ( '123 Test' )
  INSERT INTO #TEMP99( Output ) VALUES ( 'Hey, ist doch alles Oaki Doaki !!!' )
  INSERT INTO #TEMP99( Output ) VALUES ( @ParameterQ)
  SELECT * FROM #TEMP99 
END
Hier die Delphi-Seite (ich verwende TADOStoredProc):
Delphi-Quellcode:
   ADOStoredProc1.Active := False;
   ADOStoredProc1.ProcedureName := 'Test2';
   ADOStoredProc1.Parameters.Refresh;
   ADOStoredProc1.Parameters.ParamValues['ParameterQ'] := 'Delphi-Praxis';
   ADOStoredProc1.Active := True;
Datasource mit ADOStoredProc1 verbinden; diese mit einem DBGrid; fertig. :bounce2:


Hmm bei gelegenheit test ichs mal...
Wollte aber nicht wirklich andere Komponenten mit einbaun...


Aber warum Bekomm ich das bei mir nicht als Recordset zurück?
Hab bisle experimentiert und habe am anfang der Procedure NOCOUNT An gemacht und nun kommt es als Recordset zurück...

Aber was bewirkt dieses NOCOUNT?


Bye


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:11 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz