Benutzer mit den meisten Antworten
Wechsel von SQL2000 zu SQL2008

Frage
-
Hallo zusammen,
wir betreiben seit vielen Jahren eine Website mit ASP und SQL2000. Alles funktioniert soweit einwandfrei, allerdings ist die Geschwindigkeit, bedingt durch immer weiter steigende Datenvolumen, nicht mehr optimal.
Also soll jetzt der Umstieg auf SQL2008 vorgenommen werden.
Wenn ich also die ASP-Seiten gegen eine Kopie der Datenbank auf einem SQL2008-Datenbankserver verlinke, funktoniert ein Teil der Seiten scheinbar problemlos, bei anderen scheint es Anpassungsbedarf zu geben.
Konkret scheint ein Problem in folgender Kombination zu liegen:
DIM lanr, rslnr, cmd, dDate Set cmd = Server.CreateObject("ADODB.Command") Set rs = Server.CreateObject("ADODB.Recordset") cmd.ActiveConnection = con
Folgender Part scheint soweit normal zu funktionieren:cmd.CommandText = "sp_Get_lieferanschriftnummer_by_example '" & _ qstr(strname1) & "', '" & qstr(strname2) & "', '" & qstr(strname3) & "', '" & qstr(strstrasse) & "', '" & _ qstr(strplz) & "', '" & qstr(strort) & "', '" & qstr(strBemerkung) & "', '" & _ qstr(strEtage) & "', '" & qstr(strAbteilung) & "', " & strKundenNrAktuell & ", '" & strKuerzel & "', '" & session("PartnerOrt") & "'" rs.Open cmd if not rs.EOF then rslnr = rs.Fields(0) else rslnr = 0 end if rs.Close cmd.CommandText = "sp_INS_Bestellung_Values3 " & _ strKundenNrAktuell & ", '" & qstr(StrBenutzer) & "', '" & qstr(strBestelltext) & "', '" & _ qstr(strkostenstelle) & "', '" & strkostentraeger & "', '" & strProjekt & "', '" & _ qstr(strStatus) & "', '" & strKuerzel & "', '" & _ qstr(strname1) & "', '" & qstr(strname2) & "', '" & qstr(strname3) & "', '" & qstr(strstrasse) & "', '" & _ qstr(strplz) & "', '" & qstr(strort) & "', '" & qstr(strBemerkung) & "', '" & _ qstr(strEtage) & "', '" & qstr(strAbteilung) & "', '" & session("PartnerOrt") & "', " & rslnr & " , '" & date() & "'" Response.Write "<p>" & cmd.CommandText & "</p>" cmd.Execute
Und ab hier vermute ich das Problem:
'Response.Write(cmd.CommandText) cmd.CommandText = "spWebGetNeueBestellNummer" rs.Open cmd DIM strNeuBestellNr if not rs.EOF then strNeuBestellNr = rs.Fields(0) end if rs.Close session("Bestellnr") = strNeuBestellNr
In strNeuBestellNr scheint nix anzukommen, somit kommt auch in session("Bestellnr") kein Wert an und das führt dann dazu, daß später folgende Programme auf Grund der fehlenden BestellNr nicht mehr richtig verarbeiten werden können.
Der Fehler scheint unabhängig davon zu sein, ob die Datenbankkopie als kompatibel zu SQL2000 oder kompatibel zu SQL2008 ausgeführt wird.
Die ASP-Seiten sind eigentlich unverändert, lediglich der Connection-String wurde auf das veränderte Backend angepaßt:
strConnString = "Provider=SQLOLEDB.1;Password=xxxxx;Persist Security Info=True;User ID=yyyyy;Initial Catalog=BSM WWW Kopie;Data Source=DEV03"
als auch
strConnString = "Provider=SQLNCLI10;Password=xxxxx;Persist Security Info=True;User ID=yyyyy;Initial Catalog=BSM WWW Kopie;Data Source=DEV03"
Das Problem tritt auf, egal mit welchem Connection-String die Verbindung zur Datenbank hergestellt wird.Die StoredProc spWebGetNeueBestellNummer:
SET ANSI_NULLS OFF GO SET QUOTED_IDENTIFIER OFF GO CREATE PROCEDURE [dbo].[spWebGetNeueBestellNummer] AS SELECT IDENT_CURRENT( 'www input Bestell-Header') as [KD-Bestell-Nr]
- Bearbeitet Robert BreitenhoferModerator Dienstag, 1. Juni 2010 09:56 Formatierung
Antworten
-
Hallo Peter,
für Ident_Current reicht es völlig aus, wenn man zumindest SELECT Rechte auf der Tabelle; Vermerk dazu habe ich in der Doku nicht gefunden, aber es ausprobiert und ist ja auch (fast) logisch; man muss zumindest Daten aus der Tabelle lesen dürfen, um auch den letzten Wert erfahren zu dürfen. Mit Scope_Identity ist es genaus so. "Nur" INSERT Rechte gehen ebenso.
Mit MAX() zu arbeiten, wird igendwann mal daneben gehen, Elmar hatte es ja auch schon gesagt. Eine weitere Option wäre, mit der OUTPUT Klause des INSERT Befehles zu arbeiten, um die ID(s) zu ermitteln.
Olaf Helper ----------- * cogito ergo sum * errare humanum est * quote erat demonstrandum * Wenn ich denke, ist das ein Fehler und das beweise ich täglich http://olafhelper.over-blog.de- Als Antwort markiert Robert BreitenhoferModerator Dienstag, 15. Juni 2010 15:14
- Tag als Antwort aufgehoben PHundhausen Dienstag, 27. Juli 2010 12:33
- Als Antwort markiert PHundhausen Dienstag, 27. Juli 2010 12:35
-
Hallo zusammen,
so wie es aussieht, waren wir wohl alle gemeinsam auf 'nem falschen Dampfer unterwegs.
Also, ich habe nun versucht, meine behelfsmäßig geänderte StoredProc mit select max(BestellNr) from tabelle wieder in ein select ident_current('Tabelle') zu ändern, um dann weiter in Richtung Scope_Identity zu gehen.
Im SQLSMS funktionierte die Befehlskette korrekt; auf der Webseite jedoch nicht. Der einzige Unterschied ist der verwendete User; als ich auf der Webseite den Verbindungs-User probeweise auf SA geändert habe, funktionierte sie auf Anhieb.
Also, der User, der die Webseite mit der Datenbank verbindet, ist ein in den Rechten dramatisch gestutzter User (aus Sicherheitsaspekten). Welches Recht muß ich denn nun diesem User zusätzlich einräumen, daß er Ident_Current oder besser noch Scope_Identity verwenden kann ? Ein Betreiben der Webseite mit SA als Verbindungsuser kommt nicht in Frage.
Viele Grüße
Peter
- Als Antwort markiert PHundhausen Dienstag, 27. Juli 2010 12:35
Alle Antworten
-
Hi,
qstr(strname1) & "', '" & qstr(strname2) & "', '" & qstr(strname3) & "', '" & qstr(strstrasse) & "', '" & _
Und ab hier vermute ich das Problem:
qstr(strplz) & "', '" & qstr(strort) & "', '" & qstr(strBemerkung) & "', '" & _
qstr(strEtage) & "', '" & qstr(strAbteilung) & "', '" & session("PartnerOrt") & "', " & rslnr & " , '" & date() & "'"'Response.Write(cmd.CommandText)
cmd.CommandText = "spWebGetNeueBestellNummer"
rs.Open cmd
DIM strNeuBestellNr
if not rs.EOF then
strNeuBestellNr = rs.Fields(0)
end if
rs.Close
session("Bestellnr") = strNeuBestellNrIn strNeuBestellNr scheint nix anzukommen, somit kommt auch in session("Bestellnr") kein Wert an und das führt dann dazu, daß später folgende Programme auf Grund der fehlenden BestellNr nicht mehr richtig verarbeiten werden können.
rs.CursorLocation = 3 'adUseClient
Wenns nicht hilft, überwache die Ausführung mal mit dem SQL Server Profiler. Wenn es dasselbe ist wie bei mir damals, solltest Du sehen, dass intern jedesmal neue Verbindungen geöffnet werden.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community -
Hallo,
Zunächst verwende CommandType=adCmdStoredProc .
Im übrigen kann ich Dir nur empfehlen für alles Command-Objekte
zusammen mit Parametern zu verwenden.
Denn schon die Verketterei dürfte ihren Teil zu der Verlangsamung beitragen.Für die Prozedur verwende besser einen Ausgabe-Parameter und SCOPE_IDENTITY().
Sich auf IDENT_CURRENT verlassen ist an der Stelle mehr als gewagt,
ich verweise hier auf Managing an @@IDENTITY Crisis (die bei ADODB nicht anders ist)Eine bessere Lösung könnte angedeutet wie folgt aussehen:
SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [dbo].[sp_INS_Bestellung_Values3] @BestellNr int OUT, -- Einzufügende Werte... @Benutzer nvarchar(40) -... AS SET NOCOUNT ON; INSERT INTO dbo.Bestellung VALUES(@Benutzer, ....); IF @@ROWCOUNT = 1 BEGIN SET @BestellNr = SCOPE_IDENTITY(); RETURN 0; -- OK END RETURN 1; -- Fehler GO
Wenn Du nun den @BestellNr Parameter als adParamOutput erstellst,
so kannst Du direkt darauf zugreifen, ohne Umweg über den ebenfalls langsamen Cursor.
Und mit einem adParamReturnValue kannst Du auch die Rückgabe auswerten.
Siehe auch How To Retrieve Values in SQL Server Stored Procedures with ADOAlles zusammen könnte die Performance verbessern - denn auch ein Wechsel
auf SQL Server 2008 alleine wird bei CRUD Dingen nicht viel an Performance rausholen.Gruß Elmar
- Als Antwort markiert Robert BreitenhoferModerator Montag, 14. Juni 2010 09:55
- Tag als Antwort aufgehoben PHundhausen Dienstag, 27. Juli 2010 12:32
-
Habe gesehen, daß Ihr mir schon Lösungsvorschläge aufgezeigt habt.
Ich werde in den nächsten Tagen umgehend versuchen, die aufgeführten Vorschläge umzusetzen. Über die Ergebnisse werde ich dann umgehend berichten.
Zu den einzelnen Rand-Kommentaren muß ich folgende Erklärungen machen:
Die Site wurde ca 2001 / 2002 erstellt und seitdem täglich von vielen Usern genutzt. Als ich heute den IDENT_CURRENT gefunden habe, hatte auch ich ein mulmiges Gefühl. Aber in all den Jahren ist diesbzgl. niemals ein Fehler aufgetreten.
Die Geschwindigkeitsprobleme treten nicht in dem hier gezeigten Problembereich auf. Allein durch den Wechsel auf SQL2008 konnte ich die Laufzeit einer Abfrage von 19 Sekunden auf unter 1 Sekunden verbessern, ohne daß irgendeine Optimierung erfolgt wäre.
Gruß Peter
-
Hallo Peter,
ich wollte damit nichts kritisieren und keiner kennt den SQL Server von Anfang an auswendig,
ich lerne auch nach gut 12 Jahren dazu ;-)Zu IDENT_CURRENT gilt, das was (knapp) dokumentiert ist:
"IDENT_CURRENT ist nur bedingt geeignet, um den nächsten generierten Identitätswert vorherzusagen.
Der tatsächlich generierte Wert kann sich aufgrund von Einfügungen durch andere Sitzungen
von IDENT_CURRENT plus IDENTITY_INCR unterscheiden."Problem ist das Identitätswerte nicht an Transaktionen teilnehmen.
Und zwischenzeitlich eine andere Sitzung den Wert verändern kann.Zur Performance: Unter den vielen Faktoren, die die die Abfragegeschwindigkeit
negativ beeinflußen können, gehören Blockierungen jeder Art an erste Stelle.
Und Dein Einfüge Code ist der Form problematischer als der von mir gezeigte,
wie ich am eigenen Leibe (als ich noch ADO verwendete) erfahren konnte.Gruß Elmar
-
probier mal folgendes (vor rs.Open cmd):
rs.CursorLocation = 3 'adUseClient
Wenns nicht hilft, überwache die Ausführung mal mit dem SQL Server Profiler. Wenn es dasselbe ist wie bei mir damals, solltest Du sehen, dass intern jedesmal neue Verbindungen geöffnet werden.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
Hallo Stefan,
Hab ich schon ausprobiert; hat leider keinen Erfolg gebracht
Hab auch mit dem SQL-Profiler überwacht; intern wurde aber für den gesamten Anweisungsblock nur 1 Verbindung genutzt
Werde dann wohl als nächtes Mal den Vorschlag von Elmar durcharbeiten.
Vielen Dank für Deine Hilfe
Peter
-
Hallo Peter,
ich habe mal einen Codeschnippsel rausgesucht.
Der stammt zwar aus einer Access ADP/VBA (älteren Datums),
sollte aber den vorgeschlagenen Aufbau relativ gut zeigen:Public Function Inventur_BelegFetch( _ ByVal InventurNr As Long, _ ByRef BelegNr As Long, _ ByRef BelegPosNr As Integer) As Boolean ' Abruf einer neuen Belegnummer Dim cmd As ADODB.Command On Error GoTo ProcErr Set cmd = New ADODB.Command With cmd .CommandType = adCmdStoredProc .CommandText = "dbo.iv_InventurBelegFetch" .CommandTimeout = 5 .NamedParameters = True .Parameters.Append .CreateParameter("@RETURN_VALUE", adInteger, adParamReturnValue) .Parameters.Append .CreateParameter("@InventurNr", adInteger, adParamInput) .Parameters.Append .CreateParameter("@BelegNr", adInteger, adParamInputOutput) .Parameters.Append .CreateParameter("@BelegPosNr", adSmallInt, adParamInputOutput) Set .ActiveConnection = GetDefaultConnection() .Parameters("@InventurNr").Value = InventurNr .Parameters("@BelegNr").Value = BelegNr .Parameters("@BelegPosNr").Value = BelegPosNr .Execute Options:=adExecuteNoRecords BelegNr = .Parameters("@BelegNr").Value BelegPosNr = .Parameters("@BelegPosNr").Value End With Inventur_BelegFetch = True ProcExit: Set cmd.ActiveConnection = Nothing Set cmd = Nothing Exit Function ProcErr: LogADOErrors "BelegFetch", , cmd.ActiveConnection FormError "Beleg Nummer" Resume ProcExit End Function
Gruß Elmar- Als Antwort markiert Robert BreitenhoferModerator Montag, 14. Juni 2010 09:55
- Tag als Antwort aufgehoben PHundhausen Dienstag, 27. Juli 2010 12:33
-
Ich habe jetzt mal versucht, mich den Lösungsvorschlägen von Elmar anzunähern. Aber so richtig komme ich dabei noch nicht vorwärts.
Als erstes hab ich Probleme, eine Procedur mit einem Output-Parameter zu erstellen. Zum Testen hab ich mal folgende StoredProc erstellt:
-------------------- create PROCEDURE [dbo].[spWebGetNeueBestellNummer] @BestellNr int Out AS set @BestellNr = 12345 -------------------
Zunächst versuche ich die wie folgt auszulesen:
Declare @SQLCommand nvarchar(100), @SQLParameter nvarchar(100) Declare @Rueckgabewert int Declare @BestellNr int set @SQLCommand = 'execute spWebGetNeueBestellNummer' set @SQLParameter = '@BestellNr int OUTPUT' execute sp_executesql @SQLCommand, @SQLParameter, @BestellNr=@Rueckgabewert OUTPUT Print @Rueckgabewert
Und bekomme folgende Fehlermeldung:
Die Prozedur oder Funktion 'spWebGetNeueBestellNummer' erwartet den '@BestellNr'-Parameter, der nicht bereitgestellt wurde.
Was mache ich falsch ?
Gruß Peter
- Bearbeitet Robert BreitenhoferModerator Dienstag, 1. Juni 2010 10:01 Formatierung
-
Hallo Peter,
versuch mal den einfachen Weg, die SP direkt aufzurufen und nicht so umständlich über dynamisches SQL (den Output Parameter müsstest Du bereits in @SQLCommand übergeben):
CREATE PROCEDURE [dbo].[spWebGetNeueBestellNummer] @BestellNr int Out
AS
SET @BestellNr = 12345;
GO
Declare @BestellNr int
execute [dbo].[spWebGetNeueBestellNummer] @BestellNr OUTPUT
SELECT @BestellNr;
Olaf Helper ----------- * cogito ergo sum * errare humanum est * quote erat demonstrandum * Wenn ich denke, ist das ein Fehler und das beweise ich täglich http://olafhelper.over-blog.de- Als Antwort markiert Robert BreitenhoferModerator Montag, 14. Juni 2010 09:55
- Tag als Antwort aufgehoben PHundhausen Dienstag, 27. Juli 2010 12:33
-
Hallo Peter,
das Prozedur-Gegenstück zu dem Aufruf - etwas gekürzt:
CREATE PROCEDURE dbo.iv_InventurBelegFetch ( @InventurNr smallint, @BelegNr int = NULL OUT, @BelegPosNr smallint = NULL OUT ) /*** Name: iv_InventurBelegFetch Date: 15.11.2001 Parameter: @InventurNr smallint IN Nummer der Inventur @BelegNr int IN, OUT Abzurufende BelegNr @BelegPosNr int IN, OUT Abzurufende Beleg Positions Nr Return: 0 OK 1 Fehler (auch gesperrte Inventur) Description: Liefert die nächste Beleg Nr einer Inventur. Dies erhöht gleichzeitig die Belegnummer im Inventursatz, so dass ein Aufruf nur bei echter Nutzung geschehen sollte. Bei geperrter Inventur wird ein Fehler und NULL geliefert ***/ AS SET NOCOUNT ON -- Aus iv_Inventur DECLARE @Inventur_SperreKZ tinyint, @Inventur_BelegNr int BEGIN TRAN iv_InventurBelegFetch -- Inventur muss vorhanden und darf nicht gesperrt sein SELECT @Inventur_SperreKZ = SperreKZ, @Inventur_BelegNr = BelegNr FROM dbo.iv_Inventur WITH (UPDLOCK) WHERE InventurNr = @InventurNr IF @@ERROR <> 0 GOTO RollbackExit IF @Inventur_SperreKZ IS NULL BEGIN RAISERROR(3000012, -1, 1, 'Inventur', 'Die Inventur ist nicht vorhanden.') GOTO RollbackExit END IF @Inventur_SperreKZ > 0 BEGIN RAISERROR(3000012, -1, 1, 'Inventur', 'Die Inventur ist gesperrt.') GOTO RollbackExit END -- Beleg Nummer vergeben IF ISNULL(@BelegNr, 0) <= 0 BEGIN -- Nächste Beleg-Nummer abrufen SET @BelegNr = @Inventur_BelegNr + 1 -- Bei neuer Nummer mit 1 beginnen SET @BelegPosNr = 1 UPDATE dbo.iv_Inventur SET BelegNr = @BelegNr WHERE InventurNr = @InventurNr IF @@ERROR <> 0 GOTO RollbackExit END -- ... gekürzt ... COMMIT TRAN iv_InventurBelegFetch RETURN 0 RollbackExit: IF @@TRANCOUNT > 0 ROLLBACK TRAN iv_InventurBelegFetch RETURN 1 GO GRANT EXECUTE ON dbo.iv_InventurBelegFetch TO public GO
Gruß Elmar- Als Antwort markiert Robert BreitenhoferModerator Montag, 14. Juni 2010 09:55
- Tag als Antwort aufgehoben PHundhausen Dienstag, 27. Juli 2010 12:34
-
So, dann muß ich jetzt nur noch die ASP-Seiten dazu bringen, den Parameter auch auszulesen. Wie mache ich das am einfachsten ?
Nachstehend mal ein paar Codeschnibbel, mit denen ich hier herumexperimentiere:
--------------------------------------------------------
DIM lanr, rslnr, cmd, dDate DIM RParameter Set cmd = Server.CreateObject("ADODB.Command") Set rs = Server.CreateObject("ADODB.Recordset") 'Set RParameter = cmd.CreateParameter("Rueckgabeparameter", adBigInt, adParamOutput) Set RParameter = cmd.CreateParameter("Rueckgabeparameter", 20, 2) cmd.ActiveConnection = con cmd.CommandText = "spWebGetNeueBestellNummer @BestellNr OUTPUT" cmd.CommandType = 4 'adCmdStoredProc rs.CursorLocation = 3 'adUseClient rs.Open cmd DIM strNeuBestellNr strNeuBestellNr = @BestellNr rs.Close
----------------------------------
Dieses Segment ist noch fehlerhaft, derzeit kann ich die Seite, auf der diese Codeteile implementiert wurden, nicht aufgerufen werden.
Wo ist mein Fehler?
Gruß Peter
- Bearbeitet Robert BreitenhoferModerator Montag, 14. Juni 2010 09:39 Code Formatierung
-
Hallo Peter,
da Du den Parameter als Skalarwert zurück erhälst, brauchst Du kein RecordSet. Bei der Parameter-Definition kannst Du angeben, das die Direction=OUTPUT ist, dann steht der Wert nach cmd.Execute() im Value des Parameters zur Verfügung:
Public Sub test()
Dim con As ADODB.Connection
Dim cmd As ADODB.Command
Set con = New Connection
con.ConnectionString = "Provider=SQLNCLI10;Server=.;Database=AdventureWorks;Trusted_Connection=yes;"
con.Open
Set cmd = New Command
cmd.ActiveConnection = con
cmd.CommandText = "spWebGetNeueBestellNummer"
cmd.CommandType = adCmdStoredProc
cmd.Parameters("@BestellNr").Direction = adParamOutput
cmd.Parameters("@BestellNr").Type = adInteger
Call cmd.Execute
'Ergebnis ausgeben
Debug.Print cmd.Parameters("@BestellNr").Value
cmd.ActiveConnection = Nothing
Set cmd = Nothing
con.Close
Set con = Nothing
End Sub
Olaf Helper ----------- * cogito ergo sum * errare humanum est * quote erat demonstrandum * Wenn ich denke, ist das ein Fehler und das beweise ich täglich http://olafhelper.over-blog.de- Als Antwort markiert Robert BreitenhoferModerator Montag, 14. Juni 2010 09:56
- Tag als Antwort aufgehoben PHundhausen Dienstag, 27. Juli 2010 12:33
-
Hallo Peter,
Parameter mußt Du wie von mir und Olaf gezeigt über die Parameter Collection bekanntmachen.
Was das Verwenden von Konstanten in klassischem ASP angeht, siehe
http://www.asp101.com/articles/john/typelibs/default.aspBei der Verwendung von Ausgabe-Parametern muß man zudem beachten,
dass sie erst nach dem Schließen des letzten Recordsets (Resultset) zur Verfügung stehen.
ADO erzeugt im Standard immer ein Recordset, was durch die Angabe von.Execute Options:=adExecuteNoRecords
unterdrückt werden kann.
Im allgemeinen sollte man auf ein Mischen von Recordset(s) und Ausgabe-Variablen verzichten.
Und dazu ist die Angabe von SET NOCOUNT ON in solchen Prozeduren notwendig,
denn ansonsten erzeugt der SQL Server (ggf. leere) Recordsets für jede DML Anweisung
(auch INSERT/UPDATE/DELETE).Mehr siehe: How To Process Multiple Recordsets and Messages in ADO
Auch mal wichtig: PRB: Recordset Does Not Open with A Stored Procedure that Returns a High Severity ErrorGruß Elmar
- Als Antwort markiert Robert BreitenhoferModerator Montag, 14. Juni 2010 09:56
- Tag als Antwort aufgehoben PHundhausen Dienstag, 27. Juli 2010 12:34
-
Hier mal der aktuelle Stand:
Dank Eurer Hilfe konnte ich erfolgreich die BestellNr auslesen
Ich hab zwar noch Probleme, mit Scope_Identity oder Ident_Current die Bestell_Nr zu ermitteln, aber wenn ich einen select max(BestellNr) from tabelle verwende, funktioniert es schon mal
Die Lösung(en) entstammen nun vielen Posts aus diesem Thread, wie soll ich jetzt sinnvoll die Antwort markieren ?
An dieser Stelle herzlichen Dank für Eure Hilfe; Ihr habt mir echt weitergeholfen !
Viele Grüße
-
Hallo Peter,
ein SELECT MAX() ist im allgemeinen die schlechtere Lösung,
da bei parallen Zugriffen zum einen nicht gesagt ist das man
"seinen" Datensatz bekommt. Zum anderen ist das Konstrukt
anfällig für Blockierungen.Wenn die Nummer nicht erscheint (auch bei adParamOutput)
schau, ob Du SET NOCOUNT ON am Beginn der Prozedur hast.
Denn Ausgabeparameter stehen immer erst nach dem letzten
Recordset (Resultset) zur Verfügung.Gruß Elmar
P. S. Die Antwortmarkierungen hat Robert ja schon gesetzt.
Ansonsten hake da ab, wo Dir der Sinn danach ist - ggf.
kannst Du die hilfreichen Antworten über die zusätzliche
Schaltfläche links oben markieren.
Ich für meinen Teil bin kein Punktesammler und mir reicht
ein gelegentliches positives Feedback als solches :-) -
Hallo zusammen,
so wie es aussieht, waren wir wohl alle gemeinsam auf 'nem falschen Dampfer unterwegs.
Also, ich habe nun versucht, meine behelfsmäßig geänderte StoredProc mit select max(BestellNr) from tabelle wieder in ein select ident_current('Tabelle') zu ändern, um dann weiter in Richtung Scope_Identity zu gehen.
Im SQLSMS funktionierte die Befehlskette korrekt; auf der Webseite jedoch nicht. Der einzige Unterschied ist der verwendete User; als ich auf der Webseite den Verbindungs-User probeweise auf SA geändert habe, funktionierte sie auf Anhieb.
Also, der User, der die Webseite mit der Datenbank verbindet, ist ein in den Rechten dramatisch gestutzter User (aus Sicherheitsaspekten). Welches Recht muß ich denn nun diesem User zusätzlich einräumen, daß er Ident_Current oder besser noch Scope_Identity verwenden kann ? Ein Betreiben der Webseite mit SA als Verbindungsuser kommt nicht in Frage.
Viele Grüße
Peter
- Als Antwort markiert PHundhausen Dienstag, 27. Juli 2010 12:35
-
Hallo Peter,
für Ident_Current reicht es völlig aus, wenn man zumindest SELECT Rechte auf der Tabelle; Vermerk dazu habe ich in der Doku nicht gefunden, aber es ausprobiert und ist ja auch (fast) logisch; man muss zumindest Daten aus der Tabelle lesen dürfen, um auch den letzten Wert erfahren zu dürfen. Mit Scope_Identity ist es genaus so. "Nur" INSERT Rechte gehen ebenso.
Mit MAX() zu arbeiten, wird igendwann mal daneben gehen, Elmar hatte es ja auch schon gesagt. Eine weitere Option wäre, mit der OUTPUT Klause des INSERT Befehles zu arbeiten, um die ID(s) zu ermitteln.
Olaf Helper ----------- * cogito ergo sum * errare humanum est * quote erat demonstrandum * Wenn ich denke, ist das ein Fehler und das beweise ich täglich http://olafhelper.over-blog.de- Als Antwort markiert Robert BreitenhoferModerator Dienstag, 15. Juni 2010 15:14
- Tag als Antwort aufgehoben PHundhausen Dienstag, 27. Juli 2010 12:33
- Als Antwort markiert PHundhausen Dienstag, 27. Juli 2010 12:35
-
Hallo Olaf,
in der Tat hat es ausgereicht, dem Benutzer auf die ID-Spalte ein Select-Recht einzuräumen und schon funzt alles wieder wie gehabt. Ich habe sogar schon mal frische Kopien erzeugt, die das ganze obige Herumgeändere nicht enthalten und siehe da, nach setzen dieses Rechts scheint die Seite auf Anhieb zu funzen :-)
Werde mich jetzt mal weiteren Tests auf Funktionalität widmen ...
Nochmal vielen Dank für Eure Hilfe !
Peter
-
Hallo Peter,
da Du von SQL Server 2000 auf 2008 migrierst, schau Dir an:
Konfigurieren der Sichtbarkeit von Metadaten
denn (schon mit SQL Server 2005) wurde dort einiges geändert,
und nicht mehr jeder kriegt alles zu sehen - Was bei einer Website
i. a. auch empfehlenswert ist.Für die Ausführung von Prozeduren, wäre wichtig die EXECUTE AS Klausel
(dort auch den Links in anderen Ressourcen folgen)Gruß Elmar