Форум: "Базы";
Текущий архив: 2005.12.18;
Скачать: [xml.tar.bz2];
ВнизПередача параметра Найти похожие ветки
← →
Брат (2005-10-28 16:40) [0]Добрый вечер!
Как правильно передать параметр NULL в такой сапрос к примеру:
Insert into Customers ("Id", "Name") values (:"Id", :"Name") ?
← →
Desdechado © (2005-10-28 16:46) [1]params[0].clear
← →
Брат (2005-10-28 17:04) [2]Неа, все равно не получается :(
Вобщем опишу-ка я полностью проблему :
переганяю данные из одной базы во вторую :
DM.IBSQL.SQL.Clear;
DM.IBSQL.SQL.Add("INSERT INTO " + TableName + "("");
DM.IBSQL.SQL.Add(Fields);
DM.IBSQL.SQL.Add(") VALUES (");
DM.IBSQL.SQL.Add(Values);
DM.IBSQL.SQL.Add(")");
for i:= 1 to i<=DM.CommonQuery.RecordCount do
begin
Current_Record_ID = DM.CommonQuery.Fields.Fields[0].AsString;
for j:= 0 to j<DM.CommonQuery.Fields.Count do
begin
if (DM.CommonQuery.Fields.Fields[j].DataType == ftLargeint) then
DM.IBSQL.ParamByName(FieldsNameList.Strings[j]).AsInteger = DM.CommonQuery.Fields.Fields[j].AsInteger;
else
if (not DM.CommonQuery.Fields.Fields[j].IsNull) then
DM.IBSQL.ParamByName(FieldsNameList.Strings[j]).Value =
DM.CommonQuery.Fields.Fields[j].Value;
else
DM.IBSQL.ParamByName(FieldsNameList.Strings[j]).Value = NULL;
end
DM.IBSQL.ExecQuery;
DM.CommonQuery.Next;
end
При попытке выполнить DM.IBSQL.ExecQuery возникает ошибка
"arithmetic exception, numeric overflow, or string truncation
Cannot transliterate character between character sets"
Что интересно - все получается и никаких ошибок нет, когда я в ИБЕксперте выполняю аналогичный запрос :
INSERT INTO "Customers_Adjustments"
(
"Id","Id_Customer","Id_Branch","Name_Before","Name_After",
"Key_Before","Key_After","Id_Activity_Form_Before","Id_Activity_Form_After",
"Id_Estate_Form_Before","Id_Estate_Form_After","Zip_Code_Before","Zip_Code_After",
"Address_Before","Address_After", "OKPO_Before", "OKPO_After", "Bank_Before",
"Bank_After", "MFO_Before", "MFO_After", "Account_Before", "Account_After",
"Id_State_Before", "Id_State_After", "Id_Area_Before", "Id_Area_After",
"Id_District_Before", "Id_District_After", "Add_Phone_Code_Before",
"Add_Phone_Code_After", "Phone_Number_Before", "Phone_Number_After",
"Company_Official_Before", "Company_Official_After", "INN_Before",
"INN_After", "Reg_Number_Before", "Reg_Number_After", "Agreement_Before",
"Agreement_After", "Deleted_Before", "Deleted_After", "Editor", "Edit_Time",
"Action", "Receipt_Time")
VALUES
(588, 1, 16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"Директор","Директор",
NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, "BRANCHADMIN2",
"2004-11-22 08:04:54", "U", "2004-11-22 08:04:54");
в чем дело? куда копать? :(
← →
Брат (2005-10-28 17:08) [3]я так понимаю что дело в передаче NULL, потому что программа работает, когда переганяются данные из таблицы не содержащей значений NULL
← →
Johnmen © (2005-10-28 17:17) [4]1. Принципиальные ошибки:
здесьfor i:= 1 to i<=DM.CommonQuery.RecordCount do
целых две.
2. Есть уверенность, что типы параметров совпадают с типами полей?
3. Есть уверенность, что типы при присваивании совпадают?
← →
Брат (2005-10-28 17:29) [5]
> 2. Есть уверенность, что типы параметров совпадают с типами
> полей?
> 3. Есть уверенность, что типы при присваивании совпадают?
>
конечно, т.к. я это делаю так :
DM.CommonQuery.Fields.GetFieldNames(FieldsNameList);
for i:=0 to i<DM.CommonQuery.Fields.Count do
begin
Fields = Fields + """ +FieldsNameList.Strings[i] + "", ";
Values = Values + ":"" +FieldsNameList.Strings[i] + "", ";
end
Fields.Delete(Fields.Length-1,1);
Values.Delete(Values.Length-1,1);
← →
Zacho © (2005-10-28 17:29) [6]2 Брат :
1. Тебе уже сказали: для установки значения параметра в NULL используй метод Clear.
2. Не стоит использовать RecordCount, по крайней мере без предварительного FetchAll. Стандартный, всегда и везде работающий метод организации цикла по датасету - while not MyDataSet.Eof do ..
← →
Брат (2005-10-28 17:36) [7]
> 1. Тебе уже сказали: для установки значения параметра в
> NULL используй метод Clear.
> 2. Не стоит использовать RecordCount, по крайней мере без
> предварительного FetchAll. Стандартный, всегда и везде работающий
> метод организации цикла по датасету - while not MyDataSet.
> Eof do ..
1) пробовал clear - ничего не изменилось....
2) фетчолл стоит выше - я его в коде не привел....
← →
Zacho © (2005-10-28 17:42) [8]Брат (28.10.05 17:36) [7]
Попробуй то же самое без параметров, и посмотри какой запрос сформирует твоя процедура.
А RecordCount всё равно использовать не стоит, дурная привычка, потенциальный источник багов.
← →
Zacho © (2005-10-28 17:43) [9]Zacho © (28.10.05 17:42) [8]
Попробуй то же самое без параметров
Я имел в виду, вместо параметров сразу пихай в строку данные.
И посмотри на получившийся запрос, сразу должно быть понятно, где проблема.
← →
Desdechado © (2005-10-28 17:45) [10]что за конструкция такая странная
for i:=0 to i<DM.CommonQuery.Fields.Count do
правая граница цикла как-то интересно задана
← →
Mitko (2005-10-28 18:42) [11]Проверяй у source table если значение поля равно NULL, то ето поле не включай в запросе.
← →
Lexer © (2005-10-28 18:54) [12]Братан, выложи значение DM.IBSQL.SQL.Text, которое получается перед выполнением этого запроса. И тот код в котором ты делаешь Clear параметрам, Clear всегда работал стабильно.
← →
Deniz © (2005-10-31 07:21) [13]Это вообще что за язык?
Ты не чем пишешь?
По делу:
Вот это:
if (DM.CommonQuery.Fields.Fields[j].DataType == ftLargeint) then
DM.IBSQL.ParamByName(FieldsNameList.Strings[j]).AsInteger := DM.CommonQuery.Fields.Fields[j].AsInteger;
вообще не там, или не нужно.
Что будет если тип поля ftLargeint и там null?
...
if (not DM.CommonQuery.Fields[j].IsNull) then
DM.IBSQL.ParamByName(FieldsNameList.Strings[j]).Value := DM.CommonQuery.Fields[j].Value;
else
DM.IBSQL.ParamByName(FieldsNameList.Strings[j]).Clear;
...
← →
КиТаЯц © (2005-10-31 07:47) [14]На. Личная наработка:
cons _ = " "; // пробел
function InsSQL(Base:tIBDataBase; TableName: string;
FieldsName: array of string; NewValues: array of variant; DoCommit: boolean = True): boolean;
var ibSQL: tIBSQl; S: string; I: Integer;
begin
if (Length(FieldsName) <> Length(NewValues))
then begin
raise Exception.Create("Неправильно переданы параметры в процедуру"+_+ "InsSQL");
exit;
end;
ibSQL:= tIBSQl.Create(Base);
try
ibSQL.SQL.Add("INSERT INTO"+_+TableName+_); S:="";
for I:= 0 to High(FieldsName) do S:= S + TableName+"."+FieldsName[i]+",";
SetLength(S, Length(S)-1);
ibSQL.SQL.Add("("+S+")"+_+"VALUES"+_); S:="";
for I:= 0 to High(NewValues) do S := S+":"+IntToStr(i)+",";
SetLength(S, Length(S)-1);
ibSQL.SQL.Add("("+S+")");
for I:= 0 to High(NewValues) do begin
ibSQL.ParamByName(IntToStr(i)).IsNull:= (AnsiUpperCase(VarToStr(NewValues[i])) = "NULL");
if not ibSQL.ParamByName(IntToStr(i)).IsNull
then ibSQL.ParamByName(IntToStr(i)).Value:= NewValues[i];
end;
//showmessage("InsSQL"+#13#13+ibSQL.SQL.Text);
ibSQL.ExecQuery;
finally
ibSQL.Close; ibSQL.Free;
if DoCommit then Base.DefaultTransaction.Commit;
Base.DefaultTransaction.Active:=True;
end;//finally
Result:= True; // отработала успешно
end;
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2005.12.18;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.018 c