2014-02-07 30 views
0

我在查詢分析器中測試出一個SQL查詢和它的作品就好了,那就是:SQL與ASP語法

INSERT INTO Questions(QuestionText, QuestionType) 
VALUES('test','test') 
    DECLARE @testID int 
     SET @testID = @@identity 
     INSERT INTO Questions(QuestionText) 
     VALUES (@testID) 

(我只是測試了@@ IDENTITY函數)

但是,只要我嘗試並在我的網站上實現它(我與SQL Classic一起使用SQL),我收到一個錯誤,有人可以告訴我我做錯了嗎?以下是我已經把在asp:

set rs=Server.CreateObject("ADODB.recordset") 
     rs.Open "Select * from Questions", conn 

     sql="INSERT INTO Questions(QuestionText, QuestionType)" 
     sql=sql & " VALUES " 
     sql=sql & "('" & qtext & "'," 
     sql=sql & "'" & "checkbox" & "')" 
     sql=sql & "DECLARE @testID int" 
     sql=sql & "SET @testID = @@identity" 
     sql=sql & "INSERT INTO Questions(QuestionText)" 
     sql=sql & " VALUES " 
     sql=sql & "(@testID)" 

     on error resume next 
     conn.Execute sql,recaffected 
     if err<>0 then 
     Response.Write("An Error Has Occured") 
     else 
Response.write("Data Added") 
     end if 

     conn.close 

回答

2

您的SQL沒有空格,當您串聯,所以這樣的:

sql="INSERT INTO Questions(QuestionText, QuestionType)" 
sql=sql & " VALUES " 
sql=sql & "('" & qtext & "'," 
sql=sql & "'" & "checkbox" & "')" 
sql=sql & "DECLARE @testID int" 
sql=sql & "SET @testID = @@identity" 
sql=sql & "INSERT INTO Questions(QuestionText)" 
sql=sql & " VALUES " 
sql=sql & "(@testID)" 

將會產生

"INSERT INTO Questions(QuestionText, QuestionType) VALUES ('', '')DECLARE @testID intSET @testID = @@identityINSERT INTO Questions(QuestionText) VALUES (@testID); 

正如你所看到的,你最終會遇到無效的句法:

DECLARE @testID intSET @testID = @@identityINSERT 

速戰速決將添加空格和/或terminate your statements properly with a semi-colon

sql="INSERT INTO Questions(QuestionText, QuestionType)" 
sql=sql & " VALUES " 
sql=sql & "('" & qtext & "'," 
sql=sql & "'" & "checkbox" & "');" 
sql=sql & "DECLARE @testID int;" 
sql=sql & "SET @testID = @@identity;" 
sql=sql & "INSERT INTO Questions(QuestionText)" 
sql=sql & " VALUES " 
sql=sql & "(@testID);" 

更妙的是使用parameterised queries爲好,當前的代碼不是類型安全的,容易受到SQL注入,而不能利用查詢計劃緩存。

最後@@IDENTITY是幾乎從來沒有使用正確的函數,你應該使用SCOPE_IDENTITY()此 - See this answer for more info


編輯

我知道這只是一個原型類型的查詢進行測試,但您可以將您的查詢轉換爲單個語句,如下所示:

INSERT INTO Questions(QuestionText, QuestionType) 
OUTPUT inserted.QuestionText INTO Questions (QuestionText) 
OUTPUT inserted.QuestionText 
VALUES (?, ?); 

第一個輸出語句將再次插入您要插入到表中的QuestionText的值,第二個輸出將返回此值到ASP。

+0

謝謝你們的所有幫助,先生!我會嘗試Scope_Identity()以及這是一個原始原始原型原型,防止SQL注入即將到來。 – howdybaby

+1

@howdybaby SQL注入不是一個後來認爲構建以保護自己而不是後來添加它,如果你要使用代碼如「INSERT INTO Questions(QuestionText,QuestionType)VALUE(''& qtext&「')'你以後如何添加SQL注入?從一開始就使用'ADODB.Command',你將不會有這些問題需要回答。 – Lankymart

+0

好的,謝謝你的建議,我正在學習我去 – howdybaby

-1

這裏有兩個簡單的,並準備使用功能在傳統的ASP執行SQL東西

'--------------------------------------------------------------------------------------- 
' Generates Recordset from SQL String and either Connection String or Connection Object 
' (works with both), 3rd paramter bForUpdate (true/false) specifies if the returned 
' Recordset is read-only or allows updates 
' 
' Returns ADODB Recordset as Result 
' Example Usage: 
' 
' Dim conn : Set conn = Server.CreateObject("ADODB.Connection) 
' conn.open "YOUR CONNECTION STRING" 
' Dim rs, strSQL 
' strSQL = "Select * From Table;" 
' Set rs = GenerateRecordSet(strSQL, conn) 
' If not rs.EOF Then 
' ... 
' End If 
'--------------------------------------------------------------------------------------- 
Function GenerateRecordSet(byVal sqlstring, byVal connDSN, byVal bForUpdate) 'as ADODB.Recordset 
' Create a Recordset based on SQL Statement 
    Dim oRecSet 
    Set oRecSet = Server.CreateObject("ADODB.Recordset") 
    oRecSet.CursorLocation = 3 
    If bForUpdate Then 
     oRecSet.open sqlstring, connDSN, 3,2 
    Else 
     oRecSet.open sqlstring, connDSN 
    End If 
    Set GenerateRecordSet = oRecSet 
End Function 

'--------------------------------------------------------------------------------------- 
' Execute a Stored Procedure or sql statement without return values 
' Requires sql string to execute and either DSN connection string to database or 
' ADODB.Connection object 
' Returns Nothing* 
' (using Function instead of Sub that programmers can use FN(param) without 
' getting any errors) 
'--------------------------------------------------------------------------------------- 
Function ExecSP(byVal sqlstring, byVal connDSN) 'nothing 
    Dim bCloseConn : bCloseConn = False 
    If Not isObject(connDSN) Then 
     Dim connStr : connStr = connDSN 
     bCloseConn = True 
     Set connDSN = Server.CreateObject("ADODB.Connection") 
     connDSN.ConnectionTimeout = 10000 
     connDSN.CommandTimeout = 10000 
     connDSN.Open connStr 
    End If  
    connDSN.Execute "SET DEADLOCK_PRIORITY LOW" 'Optional, you can comment it out, if not needed 
    connDSN.Execute sqlstring 
    If bCloseConn Then 
     connDSN.close 
     Set connDSN = Nothing 
    End If 
End Function 
+0

個人不會這樣做,但無論如何幾筆記 - 使用'<! - 元數據類型=「typelib」文件=「c:\ program files \ common files \ system \ ado \ msado15.dll」 - >'(根據需要更改msado15.dll路徑),以便可以使用ADO內置常量而不是硬編碼值。如果您只是使用記錄集來顯示數據,還可以使用'GetRows'將記錄集返回給數組,看[這篇文章](http://databases.aspfaq。com/database/should-i-use-recordset-iteration-or-getrows-or-getstring.html)進行比較。 – Lankymart