|
| Kan ikke få værdie ud af det der retuneres~ Fra : PNR |
Dato : 29-10-03 19:52 |
|
Jeg har følgende stored procedure:
CREATE PROC indsaetNyKunde
(
@navn varchar(50),
@adresse varchar(50),
@postnr int,
@tlf nvarchar(20),
@brugernavn nvarchar(30),
@dato varchar(30),
@forhandlernr nvarchar(40),
@adgangskode nvarchar(15),
@kundenr varchar(10) = null output
)
AS
begin
select @kundenr = MAX(kundenr) FROM Bruger
select @kundenr = @kundenr + 1
INSERT INTO bruger
(kundenr, brugernavn, adgangskode, navn, adresse, postnr, tlf, dato,
forhandlernr)
VALUES
(@kundenr,
@brugernavn,@adgangskode,@navn,@adresse,@postnr,@tlf,@dato,@forhandlernr)
end
GO
laver så følgende i ASP:
sqlFor = "EXECUTE indsaetNyKunde '" & navn & "','" & adresse & "','" &
postnr & "','" & tlf & "','" & brugernavn & "','" & now() & "','" &
session("forhandlernr") & "','" & adgangskode & "';"
set rs = Server.CreateObject("ADODB.Recordset")
rs = cn.execute(sqlFor)
response.write "kundenr: " & rs("kundenr") <-- Dette er linie 85
Og får følgende fejl:
ADODB.Fields error '800a0cc1'
Item cannot be found in the collection corresponding to the requested name
or ordinal.
/opretBruger.asp, line 85
// Peter
| |
Peter Lykkegaard (29-10-2003)
| Kommentar Fra : Peter Lykkegaard |
Dato : 29-10-03 20:31 |
|
PNR wrote:
> @kundenr varchar(10) = null output
------------------------------------^^^^
Her bruger du en output parameter
Det virker _kun_ sammen med command objektet - svjh
>
> sqlFor = "EXECUTE indsaetNyKunde ...
----------------^^^^^^
Jeg mener ikke at du skal bruge execute her?
(kun i QA)
> set rs = Server.CreateObject("ADODB.Recordset")
> rs = cn.execute(sqlFor)
> response.write "kundenr: " & rs("kundenr") <-- Dette er linie 85
>
Error:
> Item cannot be found in the collection corresponding to the requested
> name or ordinal.
Din update statement returnerer et "tomt" recordset
Prøv at løbe fields collection igennem i debugger view
Hvis du vil bruge output parametre så kan du evt hente lidt inspiration her
http://www.asp-faq.dk/article/?id=102
Ellers skal du lave noget ala
CREATE PROC indsaetNyKunde
(
@navn varchar(50),
@adresse varchar(50),
@postnr int,
@tlf nvarchar(20),
@brugernavn nvarchar(30),
@dato varchar(30),
@forhandlernr nvarchar(40),
@adgangskode nvarchar(15),
)
AS
begin
declare @kundenr varchar(10)
select @kundenr = MAX(kundenr) + 1 FROM Bruger
INSERT INTO bruger
(kundenr, brugernavn, adgangskode, navn, adresse, postnr, tlf, dato,
forhandlernr)
VALUES
(@kundenr,
@brugernavn,@adgangskode,@navn,@adresse,@postnr,@tlf,@dato,@forhandlernr)
select @kundenr
end
Men bortset fra hvorfor laver du kundenummer vha denne metode
Det er mere effektivt og sikkert at bruge en identity kolonne
Den sidste værdi kan hentes vha variablen @@Identity
- Peter
| |
Peter Nørregaard Ras~ (30-10-2003)
| Kommentar Fra : Peter Nørregaard Ras~ |
Dato : 30-10-03 09:55 |
|
Jeg syntes stadig ikke jeg kan få det til at virke, kan du evt hjælpe mig
med at omskrive min kode så det virker? evt ved bruge af disse command
parameter?
//Peter
"Peter Lykkegaard" <polonline@hotmail.dk> skrev i en meddelelse
news:3fa014df$0$27458$edfadb0f@dread16.news.tele.dk...
> PNR wrote:
>
> > @kundenr varchar(10) = null output
> ------------------------------------^^^^
>
> Her bruger du en output parameter
> Det virker _kun_ sammen med command objektet - svjh
> >
> > sqlFor = "EXECUTE indsaetNyKunde ...
> ----------------^^^^^^
>
> Jeg mener ikke at du skal bruge execute her?
> (kun i QA)
>
> > set rs = Server.CreateObject("ADODB.Recordset")
> > rs = cn.execute(sqlFor)
> > response.write "kundenr: " & rs("kundenr") <-- Dette er linie 85
> >
> Error:
> > Item cannot be found in the collection corresponding to the requested
> > name or ordinal.
>
> Din update statement returnerer et "tomt" recordset
> Prøv at løbe fields collection igennem i debugger view
>
> Hvis du vil bruge output parametre så kan du evt hente lidt inspiration
her
> http://www.asp-faq.dk/article/?id=102
>
> Ellers skal du lave noget ala
>
> CREATE PROC indsaetNyKunde
> (
> @navn varchar(50),
> @adresse varchar(50),
> @postnr int,
> @tlf nvarchar(20),
> @brugernavn nvarchar(30),
> @dato varchar(30),
> @forhandlernr nvarchar(40),
> @adgangskode nvarchar(15),
> )
> AS
> begin
> declare @kundenr varchar(10)
>
> select @kundenr = MAX(kundenr) + 1 FROM Bruger
>
> INSERT INTO bruger
> (kundenr, brugernavn, adgangskode, navn, adresse, postnr, tlf, dato,
> forhandlernr)
> VALUES
> (@kundenr,
> @brugernavn,@adgangskode,@navn,@adresse,@postnr,@tlf,@dato,@forhandlernr)
>
> select @kundenr
>
> end
>
> Men bortset fra hvorfor laver du kundenummer vha denne metode
> Det er mere effektivt og sikkert at bruge en identity kolonne
>
> Den sidste værdi kan hentes vha variablen @@Identity
>
> - Peter
>
>
| |
Peter Lykkegaard (30-10-2003)
| Kommentar Fra : Peter Lykkegaard |
Dato : 30-10-03 20:19 |
|
Peter Nørregaard Rasmussen wrote:
> Jeg syntes stadig ikke jeg kan få det til at virke, kan du evt hjælpe
> mig med at omskrive min kode så det virker? evt ved bruge af disse
> command parameter?
>
Jeg har droppet sp's i forbindelse med mine udviklingsprojekter, da jeg
hovedsagligt arbejder med meget kundespefikke løsninger
I et af mine egne projeker kunne jeg lave det ala nedenstående
(simplificeret)
NB! - Det er ikke testet
Læs mere om command objektet her
http://www.asp-faq.dk/article/?id=102
- Peter
' Consts kommer evt fra adovbs.inc (SSI)
'---- ParameterDirectionEnum Values ----
Const adParamInput = &H0001
Const adParamOutput = &H0002
'---- DataTypeEnum Values ----
Const adInteger = 3
Const adVarChar = 200
'---- CommandTypeEnum Values ----
Const adCmdText = &H0001
'---- ExecuteOptionEnum Values ----
Const adAsyncExecute = &H00000010
Const adAsyncFetch = &H00000020
Const adAsyncFetchNonBlocking = &H00000040
Const adExecuteNoRecords = &H00000080
'---- ObjectStateEnum Values ----
Const adStateClosed = &H00000000
Private mobjAddCustomer
Private mobjConn
Function AddCustomer(
CUserID, CPassword, CName, CAddress, CPhone, CDate, CPartner _
)
Dim objParam
Dim lngRecordsAffected
If Not IsObject(mobjAddCustomer) Then
Set mobjAddCustomer = CreateObject("ADODB.Command")
With mobjAddCustomer
' Assuming we have a live connection
Set .ActiveConnection = mobjConn
.CommandType = adCmdText
.CommandText = _
"Declare @CustomerID VarChar(10) " & _
"SELECT @CustomerID = Max(CustomerID) + 1 From tblCustomer "
& _
"INSERT INTO tblCustomer (" & _
"CustomerID, CUserID, CPassword, CName, CAddress,
CZipCode, CPhone, CDate, CPartner) " & _
"VALUES (@CustomerID, ?, ?, ?, ?, ?, ?, ?, ? ") & _
"Select ? = @CustomerID"
' Persist using prepared statement
.Prepared = True
Set objParam = .Parameters
objParam.Append .CreateParameter("CUserID", adVarChar,
adParamInput, 30)
objParam.Append .CreateParameter("CPassword", adVarChar,
adParamInput, 15)
objParam.Append .CreateParameter("CName", adVarChar,
adParamInput, 50)
objParam.Append .CreateParameter("CAddress", adVarChar,
adParamInput, 50)
objParam.Append .CreateParameter("CZipCode", adVarChar,
adParamInput, 20)
objParam.Append .CreateParameter("CPhone", adVarChar,
adParamInput, 20)
objParam.Append .CreateParameter("CDate", adVarChar,
adParamInput, 30)
objParam.Append .CreateParameter("CPartner", adVarChar,
adParamInput, 40)
objParam.Append .CreateParameter("CustomerID", adVarChar,
adParamOutput, 10)
End With
End If
Set objParam = mobjAddCustomer.Parameters
objParam.Fields("CUserID").Value = CUserID
objParam.Fields("CPassword").Value = CPassword
objParam.Fields("CName").Value = CName
objParam.Fields("CAddress").Value = CAddress
objParam.Fields("CZipCode").Value = CZipCode
objParam.Fields("CPhone").Value = CPhone
objParam.Fields("CPartner").Value = CPartner
mobjAddCustomer.Execute lngRecordsAffected, , adExecuteNoRecords
AddCustomer = objParam.Fields("CustomerID").Value & ""
Set objParam = Nothing
End Function
| |
Morten R. Rasmussen (30-10-2003)
| Kommentar Fra : Morten R. Rasmussen |
Dato : 30-10-03 00:51 |
|
Den vigtigeste fejl ligger her:
> rs = cn.execute(sqlFor)
rs vil kune indeholde antallet af berørte records, og ikke et recordset.
Og selv om den returnerede et recordset, ville det stadig fejle, da du skal
bruge
Set rs=...
INSERT returnerer ikke et recordet, så hvis du vil have det sidste kunde
nummer tilbage, skal du have en
select @kundenummer
til sidst i din procedure, og bruge
Set rs = cn.execute(sqlFor)
- Morten
| |
Peter Nørregaard Ras~ (30-10-2003)
| Kommentar Fra : Peter Nørregaard Ras~ |
Dato : 30-10-03 12:42 |
|
Jeg har nu prøvet følgende:
CREATE PROC indsaetNyKunde
(
@navn varchar(50),
@adresse varchar(50),
@postnr int,
@tlf nvarchar(20),
@brugernavn nvarchar(30),
@dato varchar(30),
@forhandlernr nvarchar(40),
@adgangskode nvarchar(15)
)
AS
begin
declare @kundenr varchar(10)
select @kundenr = MAX(kundenr) + 1 FROM Bruger
INSERT INTO bruger
(kundenr, brugernavn, adgangskode, navn, adresse, postnr, tlf,
dato,forhandlernr)
VALUES
(@kundenr,@brugernavn,@adgangskode,@navn,@adresse,@postnr,@tlf,@dato,@forhan
dlernr)
select @kundenr
end
GO
Og asp:
sql = "indsaetNyKunde 'peter','vester','7400','1234','hej','" & now() &
"','1','1234';"
response.write sql
set rs = cn.execute(sql)
response.write rs("@kundenr")
og det virker stadig ikke
- PETER -
"Morten R. Rasmussen" <mortrr@liamtoh.com> skrev i en meddelelse
news:3fa0525e$0$29361$edfadb0f@dread15.news.tele.dk...
> Den vigtigeste fejl ligger her:
> > rs = cn.execute(sqlFor)
>
> rs vil kune indeholde antallet af berørte records, og ikke et recordset.
> Og selv om den returnerede et recordset, ville det stadig fejle, da du
skal
> bruge
> Set rs=...
>
> INSERT returnerer ikke et recordet, så hvis du vil have det sidste kunde
> nummer tilbage, skal du have en
> select @kundenummer
> til sidst i din procedure, og bruge
> Set rs = cn.execute(sqlFor)
>
> - Morten
>
>
| |
Jens Gyldenkærne Cla~ (30-10-2003)
| Kommentar Fra : Jens Gyldenkærne Cla~ |
Dato : 30-10-03 13:02 |
|
Peter Nørregaard Rasmussen skrev:
> Jeg har nu prøvet følgende:
Allerførst - jeg ville følge den model Peter Lykkegaard har angivet
- beholde din outputparameter, men bruge en ADO-command i stedet
for et postsæt.
De følgende kommentarer går på din nuværende løsningsmodel
> begin
Hvis du skal have et postsæt returneret - og din SP kører flere
kommandoer - vil jeg anbefale følgende trick:
SET NOCOUNT ON
- placeres som det første i din SP.
SET NOCOUNT OFF
- sættes umiddelbart før den SELECT-sætning du vil returnere. Flere
sql-kald i en sp kan ellers forvirre ADO.
> declare @kundenr varchar(10)
Hvorfor bruger du varchar til et kundenummer?
> INSERT INTO bruger
> (kundenr, brugernavn, adgangskode, navn, adresse, postnr, tlf,
> dato,forhandlernr)
> VALUES
> (@kundenr,@brugernavn,@adgangskode,@navn,@adresse,@postnr,@tlf,
> @dato,@forhan dlernr)
Jeg kan se at du kalder sp'en med datoværdien now() fra asp. Du kan
slippe for nogle potentielle fejlkilder ved at bruge GETDATE() i
sp'en i stedet. Hvis datoen altid skal være "dags dato" kan du helt
undvære dato-parameteren (man kan også sætte default-værdien i
tabellen til GETDATE())
> select @kundenr
Her vil jeg tro du mangler et alias. Prøv med
SELECT @kundenr as kundenr
> og det virker stadig ikke
Lige en helt generel ting omkring debatteknik. Det er svært at få
noget fornuftigt ud af udsagnet "det virker ikke". Hvis du derimod
fortalte *hvordan* det ikke virkede - fx at det gav fejlmeddelelsen
"Syntax error in xxx" ville det være lettere (og hurtigere) at
hjælpe. Tag et kig på siden her for at se hvad der er relevant at
medtage: < http://www.asp-faq.dk/article/?id=41>.
NB: Når du kommenterer indlæg så skriv venligst neden under det du
kommenterer og klip resten væk. På den måde er det lettere at følge
tråden. Se evt. linket i min signatur.
--
Jens Gyldenkærne Clausen
Svar venligst under det du citerer, og citer kun det der er
nødvendigt for at forstå dit svar i sammenhængen. Se hvorfor og
hvordan på http://usenet.dk/netikette/citatteknik.html
| |
|
|