Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.12.18;
Скачать: CL | DM;

Вниз

Передача параметра   Найти похожие ветки 

 
Брат   (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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.032 c
5-1116963546
w666w
2005-05-24 23:39
2005.12.18
Как в TListItem отрисовать TSpinEdit?


4-1128742619
Sergey7
2005-10-08 07:36
2005.12.18
Обработка сообщений, когда программа в трэе


10-1109556397
msgipss
2005-02-28 05:06
2005.12.18
Создание надстройки над Excell


14-1132816415
ANB
2005-11-24 10:13
2005.12.18
Что значит опыт для тестировщика ?


2-1133375394
Сергей А.
2005-11-30 21:29
2005.12.18
3 вопроса по взаимодействию с DBGrid