Avatar billede totalpc Seniormester
01. juli 2011 - 14:46 Der er 12 kommentarer og
1 løsning

Parameterisering af databasekald med ASP og ADO

Hej

Jeg har forsøgt at læse guiden af Softspot og herefter omskrive noget af min kode. Det er ikke helt nemt når man ikke har fatte alt hvad guiden beskriver :) Kan jeg få noget hjælpe?

Jeg har oprettet en global.asa fil med
<!-- METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4"  -->

Koden før:
<!--#include file="db.inc"-->

id=request.querystring("id")

strSQL = "SELECT * FROM noter where id=" & id
Set rs = Conn.Execute(strSQL)

#Jeg går udfra at det er her det kan være farligt med SQL injections. Korrekt?

Koden efter:
<!--#include file="db.inc"-->

id=request.querystring("id")

sql = "SELECT * FROM noter where id= ?"
Set cmd = Server.CreateObject("ADODB.Command")
set cmd.ActiveConnection = conn
cmd.CommandText = sql
cmd.CommandType = adCmdText
cmd.Parameters.Append
cmd.CreateParameter("@id", adInteger, adParamInput, 4, id)
set rs = cmd.Execute()

Jeg forstår ikke helt linie med CreateParameter. Kan den blive uddybet? Er det felterne fra basen der skal defineres eller hur?

Ovenstående giver mig:
Microsoft VBScript compilation error '800a0414'

Cannot use parentheses when calling a Sub

/sql/note_edit.asp, line 28

cmd.CreateParameter("@id", adInteger, adParamInput, 4, id)
----------------------------------------------------------^
Avatar billede totalpc Seniormester
01. juli 2011 - 14:49 #1
db.inc indeholder:

<%

Set Conn = Server.CreateObject("ADODB.Connection")
Conn.open "Provider=SQLNCLI10;Server=win2008server\MySQL;Database=xxxx.dk; Uid=xxxx; Pwd=xxxxx;"

%>

jeg kan ikke regne ud om den skal med eller laver problemer. Ja altså der skal jo henvises til basen et eller andet sted. :)
Avatar billede softspot Forsker
01. juli 2011 - 15:09 #2
Det er fordi du knækker kodelinjen (uden at benytte linecontinuation), så vil VBS ikke være med til det. Prøv i stedet dette:

sql = "SELECT * FROM noter where id= ?"
Set cmd = Server.CreateObject("ADODB.Command")
set cmd.ActiveConnection = conn
cmd.CommandText = sql
cmd.CommandType = adCmdText
cmd.Parameters.Append cmd.CreateParameter("@id", adInteger, adParamInput, 4, id)
set rs = cmd.Execute()

Jeg kan i øvrigt anbefale, at du laver en funktion til at sætte et Command-objekt op, så du ikke skal "forplumre" alle dine databaseopslag med 4 liniers triviel kode. Den kunne f.eks. se således ud (og med fordel placeres sammen med din connection-variabel i db.inc):

function GetCommand(sql)
  dim cmd
  set cmd = Server.CreateObject("ADODB.Command")
  set cmd.ActiveConnection = conn
  cmd.CommandText = sql
  cmd.CommandType = adCmdText
  set GetCommand = cmd
end function

Hvorefter din kode til at kalde databasen kommer til at se således ud:

sql = "SELECT * FROM noter where id= ?"
Set cmd = GetCommand(sql)
cmd.Parameters.Append cmd.CreateParameter("@id", adInteger, adParamInput, 4, id)
set rs = cmd.Execute()

Eller en endnu kortere version (som jeg bruger meget imod SQL Server, men jeg ved ikke om MySQL-driveren er glad for den):

sql = "SELECT * FROM noter where id= ?"
Set cmd = GetCommand(sql)
set rs = cmd.Execute(, array(id))

Hvor du altså bare smider parametre efter din SQL-sætning via et array og så lader ADO-driveren afgøre hvilken type hver parameter er (ud fra felttypen i databasen).

Bemærk at kommaet før array'et med parametrene er indsat med vilje - det er altså ikke en slåfejl :-)

NB: db.inc bør du i øvrigt kalde db.inc.asp eller noget der ender på .asp, da .inc-filer umiddelbart bare tolkes som tekstfiler og dermed kan hentes via en direkte URL => kæmpe sikkerhedsbrist! :-)
Avatar billede totalpc Seniormester
01. juli 2011 - 15:51 #3
Ja det var så en jeg kunne have undgået hvis jeg havde set ordenligt efter i din guide :)
Men jeg fik da så alligevel en del ud af din udvidet forklaring. Takker.

Jeg har valgt at lave min db.inc.asp :) til at indeholde:
<%
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.open "Provider=SQLNCLI10;Server=win2008server\MySQL;Database=xxx.dk; Uid=xxxxx; Pwd=xxxx;"

function GetCommand(sql)
  dim cmd
  set cmd = Server.CreateObject("ADODB.Command")
  set cmd.ActiveConnection = conn
  cmd.CommandText = sql
  cmd.CommandType = adCmdText
  set GetCommand = cmd
end function
%>

Og bruger denne:

sql = "SELECT * FROM noter where id= ?"
Set cmd = GetCommand(sql)
set rs = cmd.Execute(, array(id))

Men jeg får fejlen :

ADODB.Command error '800a0bb9'

Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another.

/sql/db.inc, line 11


Som er  cmd.CommandType = adCmdText
Avatar billede totalpc Seniormester
01. juli 2011 - 15:53 #4
Nå ja og det skal lige siges at min MySQL er en MS SQL server og ikke MySQL :)
Avatar billede softspot Forsker
01. juli 2011 - 17:03 #5
Det lyder som om id'et i querystring-parameteren ikke er et tal... kan det passe?
Avatar billede softspot Forsker
01. juli 2011 - 17:04 #6
Nej! Vrøvl! Prøv at indsætte den metadata-linje i selve asp-filen hvor du foretager opslaget i databasen.

Alternativt udskift adCmdText med konstanten 1 (såvidt jeg husker).
Avatar billede softspot Forsker
01. juli 2011 - 17:06 #7
Se værdierne for CommandTypeEnums her: http://msdn.microsoft.com/en-us/library/ms675946(v=VS.85).aspx
Avatar billede totalpc Seniormester
02. juli 2011 - 12:00 #8
Det virker med at indsætte MEtadata-linjen direkte i asp-filen. Så det vil sige at min global.asa fil ikke virker. Korrekt?

Alternativt kunne jeg måske indsætte det i db.inc filen?

Har lige et ar uddybende spørgsmål

1. Forskellen på de 2 metoder du viser ovenfor, er det at I den første skal man selv fortælle præcis hvilket felttype det er og i den korte finder den selv ud af det?

2. cmd.Parameters.Append cmd.CreateParameter("@id", adInteger, adParamInput, 4, id)

Kan du ikke lige kort forklare hvad de 4 værdier i parantesen er ?

3. Skal det være anderledes i en asp-fil der gemmer eller er det samme "kode" ?
Avatar billede totalpc Seniormester
02. juli 2011 - 12:03 #9
Ps.
Det virker KUN hvis metada er i sammen asp-fil.
Desværre heller IKKE hvis den ligger i db.inc filen
Avatar billede softspot Forsker
02. juli 2011 - 15:35 #10
Har du lagt metadata-linjen udenfor script-tags i global.asa og ligger global.asa i roden af din webapplikation?

I din asp-fil, skal metatags ligge i toppen af filen (udenfor ASP-sektioner).

Ad 1. Ja. Den lange metode er nok mest relevant i samspil med stored procedures, hvor man SKAL angive parametre og værdier i samme rækkefølge og med samme navngivning af parametre, som de er defineret i den SP der kaldes.

Ad 2. Parametrene er i nævnte rækkefølge: parameternavnet, datatypen, angivelse af om parameteren er input/output/begge dele, derefter datatypens størrelse (i bytes) og til sidst værdien parameteren skal have.
Det er ikke altid strengt nødvendigt at angive alle parametrene til CreateParameter, da visse datatyper giver sig selv eller har en standardværdi.

Ad 3. Koden er i princippet den samme for opdateringer, som for læsning. Der er en forskel på opsætningen af Command-objektet, når du vil bruge stored procedures (så skal CommandType sættes til adCmdStoredProc i stedet for adCmdText).
Avatar billede totalpc Seniormester
05. juli 2011 - 14:19 #11
Takker
Smider du ikke et svar?
Avatar billede softspot Forsker
05. juli 2011 - 15:01 #12
Jo, det gør jeg da :-)

Velbekomme!
Avatar billede totalpc Seniormester
06. juli 2011 - 09:48 #13
Og husk at holde øje med indlæg med samme overskrift...så er det sikkert mig der prøver at komme videre med tilretningen af resten af min side ;)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester