webForumDet fria alternativet

problem med Prepared Statements

18 svar · 611 visningar · startad av Vinnaren

VinnarenMedlem sedan sep. 2005833 inlägg
#1

Hej

Jag får inte följande kod att fungera :stud

					Set dbCommand = Server.CreateObject("ADODB.Command")
					Set dbCommand.ActiveConnection = Conn
					
											
					IF NOT Request.QueryString("katID") = "" THEN
					
						katID = SafeSQL(CLng(Request.QueryString("katID")))
						
						dbCommand.CommandText = "SELECT portfolio.potID, portfolio.katID AS portfolio_katID, portfolio.potRubrik, portfolio.potIngress, portfolio.potBeskrivning, portfolio.potBild, portfolio.potStatus, kategori.katID AS kategori_katID, kategori.katNamn, kategori.katTyp FROM kategori LEFT OUTER JOIN portfolio ON kategori.katID=portfolio.katID WHERE portfolio.katID = ? AND kategori.katTyp = 1 AND portfolio.proStatus = 1 ORDER BY portfolio.potID DESC"
							
						dbCommand.Parameters.Append (dbCommand.CreateParameter("katID", adChar, adParamInput, Len(katID), katID))
						
					ELSE
					
						dbCommand.CommandText = "SELECT portfolio.potID, portfolio.katID AS portfolio_katID, portfolio.potRubrik, portfolio.potIngress, portfolio.potBeskrivning, portfolio.potBild, portfolio.potStatus, kategori.katID AS kategori_katID, kategori.katNamn, kategori.katTyp FROM kategori LEFT OUTER JOIN portfolio ON kategori.katID=portfolio.katID WHERE kategori.katTyp = 1 AND portfolio.proStatus = 1 ORDER BY portfolio.potID DESC"
					
					END IF
						
					Set rs = dbCommand.Execute								
									
                       	Response.Write "<h4>"&rs("katNamn")&"</h4>"
								
								
						IF NOT (rs("potRubrik") = "" OR rs("potRubrik") = null) THEN
							DO WHILE NOT rs.EOF
								Response.Write rs("potRubrik")
							rs.MoveNext
							Loop
						END IF							
										
					rs.Close     
   					Set rs = Nothing
					Set dbCommand = Nothing

När den understa sql satsen ska köras får jag följande felmeddelande:

Det har inte angetts något värde för en eller flera nödvändiga parametrar.

på raden:

Set rs = dbCommand.Execute

Hur löser jag detta?? Man kanske inte kan ha if-sats runt om mina sql satser?

Tacksam för all hjälp

emissionMedlem sedan dec. 19996 721 inlägg
#2

TIPS: Eftersom SQL-satserna är närmast identiska så bör du kunna göra det enklare. För in villkoret i SQL-satsen om det behövs.

I övrigt ser jag 6 fel:

1. Du kör SafeSQL på värdet. En av de viktigaste aspekterna med parametriserade frågor är att de är säkrade mot injection. Det är inte bara onödigt att använda SafeSQL, utan det gör också att värdet som faktiskt stoppas in i databasen är det tillfixade värdet (med dubbla apostrofer)
2. Du kör både SafeSQL och clng på värdet. Clng kan inte returnera något som SafeSQL kan bita på.
3. Du har angivit adChar som datatyp. Är det verkligen en char-kolumn? Clng-konverteringen indikerar något annat.
4. Du hoppar direkt på rs("katNamn") etc. utan att kolla rs.EOF
5. Kontroll av null ska göras med isnull(rs("potRubrik")) och ta gärna bort de ointressant posterna redan i SQL-frågan i stället.
6. Du kollar "potRubrik" för första raden, och loopar sedan på med alla.

VinnarenMedlem sedan sep. 2005833 inlägg
#3

hmm, oki. Har nu ändrat lite men får fortfarande samma felmeddelande :(

					Set dbCommand = Server.CreateObject("ADODB.Command")
					Set dbCommand.ActiveConnection = Conn
					
											
					IF NOT Request.QueryString("katID") = "" THEN
										
							katID = Clng(Request.QueryString("katID"))
						
						dbCommand.CommandText = "SELECT portfolio.potID, portfolio.katID AS portfolio_katID, portfolio.potRubrik, portfolio.potIngress, portfolio.potBeskrivning, portfolio.potBild, portfolio.potStatus, kategori.katID AS kategori_katID, kategori.katNamn, kategori.katTyp FROM kategori LEFT OUTER JOIN portfolio ON kategori.katID=portfolio.katID WHERE portfolio.katID = ? AND kategori.katTyp = 1 AND portfolio.proStatus = 1 ORDER BY portfolio.potID DESC"
							
						dbCommand.Parameters.Append (dbCommand.CreateParameter("katID", adInt, adParamInput, CInt(katID)))
						
					ELSE
					
						dbCommand.CommandText = "SELECT portfolio.potID, portfolio.katID AS portfolio_katID, portfolio.potRubrik, portfolio.potIngress, portfolio.potBeskrivning, portfolio.potBild, portfolio.potStatus, kategori.katID AS kategori_katID, kategori.katNamn, kategori.katTyp FROM kategori INNER JOIN portfolio ON kategori.katID = portfolio.katID WHERE portfolio.proStatus = 1 ORDER BY portfolio.potID DESC"
					
					END IF
						
					Set rs = dbCommand.Execute	
												
						IF NOT rs.EOF THEN			
                       							
								
							DO WHILE NOT (rs.EOF AND isnull(rs("potRubrik")))
								Response.Write rs("potRubrik")
							rs.MoveNext
							Loop
						END IF						
										
					rs.Close     
   					Set rs = Nothing
					Set dbCommand = Nothing

Vad kan det vara för fel :q

emissionMedlem sedan dec. 19996 721 inlägg
#4

EOF-kollen är fortfarande fel. Man kan inte kolla EOF och samtidigt ett värde från samma RS.

Vad använder du för databas. ConnectionString? Du har definerat konstanterna adInt etc. någonstans (adovbs.inc)?

<%
set dbCommand = Server.CreateObject("ADODB.Command")
set dbCommand.ActiveConnection = Conn

			
SQLSelect="SELECT portfolio.potID, portfolio.katID AS portfolio_katID, portfolio.potRubrik, portfolio.potIngress, portfolio.potBeskrivning, portfolio.potBild, portfolio.potStatus, kategori.katID AS kategori_katID, kategori.katNamn, kategori.katTyp FROM kategori INNER JOIN portfolio ON kategori.katID=portfolio.katID "

if not Request.QueryString("katID") = "" then
					
	katID = Clng(Request.QueryString("katID"))
	
	SQLWHere=" WHERE portfolio.potRubrik IS NOT NULL AND portfolio.katID = ? AND kategori.katTyp = 1 AND portfolio.proStatus = 1 " 
	dbCommand.Parameters.Append (dbCommand.CreateParameter("katID", adInt, adParamInput, CInt(katID)))
	
else

	SQLWHere=" WHERE portfolio.potRubrik IS NOT NULL AND portfolio.proStatus = 1 "

end if

dbCommand.CommandText=SQLSelect & SQLWhere & " ORDER BY portfolio.potID DESC"
	
set rs = dbCommand.Execute	
							
do while not rs.EOF 
	Response.Write rs("potRubrik")
	rs.MoveNext
loop
					
rs.Close     
set rs = Nothing
set dbCommand = Nothing
%>
VinnarenMedlem sedan sep. 2005833 inlägg
#5

jag anv access som databas. har följande:

    
Conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
              "Persist Security Info=False;" & _
              "Data Source=" & Server.MapPath("../databas.mdb") & ";"

Vad konstanterna adInt kommer ifrån vet jag inte redigt, var något exempel jag hittade som jag försöker anpassa, men det vill inte fungera :r

Får fortfarande samma felmeddelande x(

emissionMedlem sedan dec. 19996 721 inlägg
#6

Om du inte vet var de kommer ifrån så får vi utgå från att de inte är definierade...

Börja med

Const adInteger = 3
Const adParamInput = &H0001

och byt ut adInt till adInteger

VinnarenMedlem sedan sep. 2005833 inlägg
#7

ok, gjort, men det e fortfarande samma felmeddelande :l

emissionMedlem sedan dec. 19996 721 inlägg
#8

Ok, jag har ingen erfaranhet av hur det fungerar med Access, men i princip borde det vara OK. Såg nu att längdparametern var borta...

dbCommand.CreateParameter("katID", adInt, adParamInput, [b]4[/b],CInt(katID))
VinnarenMedlem sedan sep. 2005833 inlägg
#9

hmm, det vill inte funka :(, får samma felmeddelande även om jag bara anv en sql sats. Jag har "nästan" en likadan ovanför denna som funkar som ser ut:

						<%
						Set dbCommand = Server.CreateObject("ADODB.Command")
						Set dbCommand.ActiveConnection = Conn
							dbCommand.CommandText = "SELECT katID, katNamn FROM kategori WHERE katTyp = 1 ORDER BY katNamn ASC"
						
						Set rs = dbCommand.Execute
								
						DO WHILE NOT rs.EOF
									
                        	Response.Write "<li>"&rs("katNamn")&"</li>"
										
						rs.MoveNext
						Loop
						rs.Close     
    					Set rs = Nothing
						Set dbCommand = Nothing
						%>

Den fungerar, men inte den andra. De ligger på samma sida, så det blir ingen konflikt? Borde ju gå o lösa på nott sätt? :q

Har nu räknat ut att det måste vara sql frågan som e fel, själva WHERE delen

VinnarenMedlem sedan sep. 2005833 inlägg
#10

ok, nu funkar det men inte redigt som tänkt. Jag har nu en kategori vid namn test. Den andra tabellen är tom, så jag vill få utskrivet namnet på den anropande kategorin. Det är inte bara när det finns något i den andra tabellen som kategorinamnet ska skrivas ut. Provar jag att anropa katID=1 (test) så får jag ut felmeddelandet: Undantag inträffade. på:

Response.Write "<h4>"&rs("katNamn")&"</h4>"

Hur löser jag det här? :stud

@ndersMedlem sedan juni 200032 969 inlägg
#11

Du får byta från INNER JOIN till LEFT JOIN och flytta alla eventuella villkor på den andra tabellen från WHERE-satsen till join-instruktionen. (Eventuellt tycker inte Access om det - då får du nog skippa villkoren på den andra tabellen helt)

VinnarenMedlem sedan sep. 2005833 inlägg
#12

:OO hmm, ok, har bytt till left outer join

					SQLSelect="SELECT portfolio.potID, portfolio.katID AS portfolio_katID, portfolio.potRubrik, portfolio.potIngress, portfolio.potBeskrivning, portfolio.potBild, portfolio.potStatus, kategori.katID AS kategori_katID, kategori.katNamn, kategori.katTyp FROM kategori LEFT OUTER JOIN portfolio ON kategori.katID=portfolio.katID "
					
					if not Request.QueryString("katID") = "" then
										
						katID = Clng(Request.QueryString("katID"))
						
						SQLWHere=" WHERE portfolio.katID = ? AND kategori.katTyp = 1 AND portfolio.potStatus = 1 " 
						dbCommand.Parameters.Append (dbCommand.CreateParameter("katID", adInteger, adParamInput, 4, CInt(katID)))
						
					else
					
						SQLWHere=" WHERE portfolio.potStatus = 1 AND kategori.katTyp = 1"
											
					end if

Hur ska jag göra det andra??

@ndersMedlem sedan juni 200032 969 inlägg
#13

Flytta villkoren som gäller tabellen portfolio till join-instruktionen. Som din kod är uppbyggd räcker det om du gör sisomså:

SQLWHere=" AND portfolio.potStatus = 1 WHERE kategori.katTyp = 1"
VinnarenMedlem sedan sep. 2005833 inlägg
#14

ska jag ha portfolio.katID = ? i min join sats? eller hur ska jag ha det?

@ndersMedlem sedan juni 200032 969 inlägg
#15

ska jag ha portfolio.katID = ? i min join sats?

@nders skrev:

flytta alla eventuella villkor på den andra tabellen från WHERE-satsen till join-instruktionen.

@nders skrev:

Flytta villkoren som gäller tabellen portfolio till join-instruktionen.

Dvs: Ja!

VinnarenMedlem sedan sep. 2005833 inlägg
#16

ööö, haha, e det smart? vad händer när inte portfolio.katID ska användas då?

dvs, när inte QueryStringen innehållet ett nummer, när allt ska visas som finns i tabellen portfolio?

@ndersMedlem sedan juni 200032 969 inlägg
#17

Då får du strunta i att lägga till det villkoret i joinen?

VinnarenMedlem sedan sep. 2005833 inlägg
#18

hmm, kanske blir smidigare att göra 2 sql satser, en som hämtar ut kategorinamnet o en som hämtar från portfolio. Verkar enklare iaf :OO

VinnarenMedlem sedan sep. 2005833 inlägg
#19

Löste det med 2 sql frågor, så nu funkar det perfa :bla :i

258 ms totalt · 3 externa anrop · v20260731065814-full.91fd2ad2
121 ms — hämta forumlista (db)
125 ms — hämta statistik (db)
131 ms — hämta tråd, inlägg och bilagor (db)