webForumDet fria alternativet

problem med Prepared Statements

ASP

18 svar · 611 visningar · startad av Vinnaren

Medlem sedan sep. 2005833 inlägg
Frågan#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

Medlem 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.

Medlem 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

Medlem 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
%>
Medlem 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(

Medlem 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

Medlem sedan sep. 2005833 inlägg
#7

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

Medlem 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))
Medlem 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

Medlem 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

Medlem sedan juni 200032 967 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)

Medlem 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??

Medlem sedan juni 200032 967 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"
Medlem sedan sep. 2005833 inlägg
#14

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

Medlem sedan juni 200032 967 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!

Medlem 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?

Medlem sedan juni 200032 967 inlägg
#17

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

Medlem 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

Medlem sedan sep. 2005833 inlägg
#19

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

264 ms totalt · 4 externa anrop · v20260731065814-full.1dc6f849
123 ms — deklarationer (db)
0 ms — hämta statistik (cache)
133 ms — hämta tråd, inlägg och bilagor (db)
128 ms — ändringar (db)