![](/img/trans.png)
[英]Run-time error '3708': Parameter Object is improperly defined. Inconsistent or incomplete information was provided
[英]Delphi: “Parameter object is improperly defined. Inconsistent or incomplete information was provided.”
我正在嘗試在 3 層數據庫設置中的表中插入一條記錄,並且中間層服務器在嘗試將第一個參數添加到查詢時生成上面的錯誤消息作為 OLE 異常。
我在谷歌上搜索過這個錯誤,我始終發現相同的結果:它來自在查詢中某處的字符串中有一個冒號,它 b0rks ADO 的 SQL 解析器。 這不是這里的情況。 任何地方都沒有假冒號。 我已經根據要插入的表的模式檢查並重新檢查了對象定義。 一切都檢查出來了,這讓我的同事難住了。 有誰知道還有什么可能導致這種情況? 我在這里不知所措。
我使用的是 Delphi 2007 和 SQL Server 2005。
我可以得到這個錯誤,使用 Delphi 2007 和 MSSQL Server 2008,我找到了一個解決方法。 (恕我直言,這很糟糕,但如果您的問題是由同一件事引起的,它可能對您有用。)
產生錯誤的代碼:
with TADOQuery.Create(nil)
do try
Connection := ADOConnection;
SQL.Text := ' (SELECT * FROM Stock WHERE InvCode = :InvCode ) '
+' (SELECT * FROM Stock WHERE InvCode = :InvCode ) ';
Prepared := true;
Parameters.ParamByName('InvCode').Value := 1;
Open; // <<<<< I get the "parameter object is...etc. error here.
finally
Free;
end;
我找到了兩種修復方法:
1)從SQL中刪除括號,即:
SQL.Text := ' SELECT * FROM Stock WHERE InvCode = :InvCode '
+' SELECT * FROM Stock WHERE InvCode = :InvCode ';
2) 使用兩個參數而不是一個:
with TADOQuery.Create(nil)
do try
Connection := ADOConnection;
SQL.Text := ' (SELECT * FROM Stock WHERE InvCode = :InvCode1 ) '
+' (SELECT * FROM Stock WHERE InvCode = :InvCode2 ) ';
Prepared := true;
Parameters.ParamByName('InvCode1').Value := 1;
Parameters.ParamByName('InvCode2').Value := 1;
Open; // <<<<< no error now.
finally
Free;
end;
我在搜索前面提到的異常消息時發現了這個線程。 就我而言,原因是試圖將 SQL 注釋 /* foo */ 嵌入到我的 query.sql.text 中。
(我認為看到評論在我的分析器窗口中飄過會很方便。)
無論如何 - Delphi7 討厭那個。
這里回復晚了。 就我而言,情況完全不同。
我試圖向數據庫添加一個存儲過程。
Query.SQL.Text :=
'create procedure [dbo].[test]' + #13#10 +
'@param int ' + #13#10 +
'as' + #13#10 +
'-- For the parameter you can pick two values:' + #13#10 +
'-- 1: Value one' + #13#10 +
'-- 2: Value two';
當我刪除冒號 (:) 時,它起作用了。 因為它將冒號視為參數。
我自己剛剛遇到了這個錯誤。 我正在使用 Delphi 7 使用 TAdoQuery 組件寫入 2003 MS Access 數據庫。 (舊代碼)我的查詢直接在 MS Access 中運行良好,但在 Delphi 中通過 TAdoQuery 對象失敗。 我的錯誤來自日期/時間值的冒號(向原始海報道歉)。
據我了解,Jet SQL 日期/時間格式為 #mm/dd/yyyy hh:nn:ss#(不需要 0 左填充)。
如果 TAdoQuery.ParamCheck 屬性為 True,則此格式失敗。 (感謝海報!)兩種解決方法是:a) 將 ParamCheck 設置為 False,或 b) 使用不同的日期/時間格式,即“mm/dd/yyyy hh:nn:ss”(帶雙引號)。
我測試了這兩個選項,它們都有效。
盡管雙引號日期/時間格式不是 Jet 日期/時間格式,但 Access 非常擅長靈活處理這些日期/時間格式。 我還懷疑它與 BDE/LocalSQL/Paradox(Delphi 7 的本機 SQL 和數據庫引擎)日期/時間格式(使用雙引號,如上所述)有關。 解析器可能被設計為忽略帶引號的字符串(雙引號是 BDE LocalSQL 中的字符串值分隔符),但可能會在其他非本地日期/時間格式上遇到一些問題。
SQL Server 使用單引號來分隔字符串,因此在寫入 SQL Server 表(未測試)時,它可能會代替雙引號起作用。 或者也許 Delphi TAdoQuery 對象仍然會出錯。 在這種情況下關閉 ParamCheck 可能是唯一的選擇。 如果您計划在代碼中切換 ParamCheck 屬性值,並且您不打算解析當前 SQL,那么您將通過在啟用它之前確保 SQL 屬性為空來節省一些處理時間。
我面臨與您的問題中描述的相同的錯誤。 我已經將錯誤追蹤到ADODB.pas
-> procedure TParameters.AppendParameters; ParameterCollection.Append(Items[I].ParameterObject)
procedure TParameters.AppendParameters; ParameterCollection.Append(Items[I].ParameterObject)
。
通過使用斷點,錯誤是由應該填充數據庫中的DateTime
字段的參數引發的,在我的情況下,我從未填充過該參數。 設置parameter().value:=''
解決了這個問題(我也嘗試過使用varNull
,但有一個問題 - 不是在數據庫中發送 Null ,而是查詢發送1
- varNull
的整數值)。
PS:我知道這是一個“遲到遲到”的答案,但也許有人會遇到同樣的錯誤。
當您嘗試在 SQL 中使用時間值而忘記用 QuotedStr() 包裝它時,您可能會收到此錯誤。
我得到了同樣的錯誤。 原來,這是因為存儲過程的一個參數被聲明為 varchar(max)。 使它成為 varchar(4000) 並且錯誤消失了。
我也有同樣的問題,但使用動態命令(例如更新語句)。
某些參數可能為 NULL。
我讓它工作的唯一方法是設置 parameter.DataType := ftString 和 parameter.Size := 1 而不是設置 value 。
cmdUpdate := TADOCommand.Create(Self);
try
cmdUpdate.Connection := '**Conections String**';
cmdUpdate.CommandText := 'UPDATE xx SET yy = :Param1 WHERE zz = :Param2';
cmdUpdate.Parameters.ParamByName('Param2').Value := WhereClause;
if VarIsNull(SetValue) then
begin
cmdUpdate.Parameters.ParamByName('Param1').DataType := ftString;
cmdUpdate.Parameters.ParamByName('Param1').Size := 1;
end else cmdUpdate.Parameters.ParamByName('Param1').Value := SetValue;
cmdUpdate.Execute;
finally
cmdUpdate.Free;
end;
我今天剛剛在一個 TADOQuery 上遇到了這個錯誤,它有ParamCheck := False
並且 SQL 中沒有冒號。
以某種方式將OLECMDEXECOPT_DODEFAULT參數傳遞給 TWebBrowser.ExecWB() 對我造成了這種情況:
這說明問題:
pvaIn := EmptyParam;
pvaOut := EmptyParam;
TWebBrowser1.ExecWB(OLECMDID_COPY, OLECMDEXECOPT_DODEFAULT, pvaIn, pvaOut);
這並沒有顯示問題:
pvaIn := EmptyParam;
pvaOut := EmptyParam;
TWebBrowser1.ExecWB(OLECMDID_COPY, OLECMDEXECOPT_DONTPROMPTUSER, pvaIn, pvaOut);
如果我沒記錯的話,您必須顯式地將 NULL 值添加到參數中。 如果您使用的是 TAdoStoredProc 組件,您應該在設計時執行此操作。
你在使用任何線程嗎? 我似乎記得在 ADO 連接被用於另一個同步查詢時計時器事件啟動查詢時收到此錯誤。 (計時器每分鍾檢查一次“系統可用”標志)。
您是否設置了參數的 DataType 或將其保留為 ftUnknown?
查詢中的單雙引號也可以從我剛剛遇到的情況中引發此錯誤,而且我根本沒有使用參數......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.