Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2012.01.29;
Скачать: [xml.tar.bz2];

Вниз

Передать в Format дату   Найти похожие ветки 

 
Laguna ©   (2011-10-18 15:25) [0]

При форматировании строки на ряду с числами и строками присутствует параметр как дата. Как его передать через Format? Из перечисленного в справке ничего не нашел

d = Десятичное (целое число)
e = Научный
f = Установленный
g = Генерал
m = Деньги
n = Число (плавающее)
p = Указатель
s = Строка
u = Десятичное число без знака
x = Шестнадцатеричный


А нужно вот так ... Format("%d - %s - %дата"), [10, "Строка", Now]


 
Amoeba_   (2011-10-18 15:30) [1]

Format("%d - %s - %s"), [10, "Строка", DateToStr(Now)]


 
Ega23 ©   (2011-10-18 15:31) [2]

Format("%d - %s - %s"), [10, "Строка", DateTimeToStr(Now)]

Ну или вместо DateTimeToStr можно FormatDateTime


 
Laguna ©   (2011-10-18 15:41) [3]

Дело в том, что передать дату нужно будет в таблицу с полем TDate через sql-запрос, поэтому перевод даты в строку не пойдет.


 
Amoeba_   (2011-10-18 15:48) [4]


> передать дату нужно будет в таблицу с полем TDate через
> sql-запрос

Запрос в студию!


 
OW ©   (2011-10-18 16:01) [5]


> передать дату нужно будет в таблицу с полем TDate через
> sql-запрос

use parameters


 
Ega23 ©   (2011-10-18 16:04) [6]


> нужно будет в таблицу с полем TDate через sql-запрос,


Параметры используй.


 
Laguna ©   (2011-10-18 16:06) [7]

Общая процедура для исполнения SQL-запроса

procedure SqlFromTab(St : String);
begin
 with TADOQuery.Create(nil) do
  try
    ADOConnection := DM1.AdoConnection1;
    ParamCheck := True;
    SQL.Clear;
    SQL.Add(St);
    ExecSQL;
  finally
    Free;
  end;
end;


Далее формируем нужную строку для запроса


SQlFromTab(Format("Insert InTo OperTab (Kod, , DataDoc, NameDoc, SumDoc) " +
                               "Values (%d, ???, %s, %.0f)",[RegInf.Kod, DataDocDateEdit.Date, NameDocEdit.Text, DBGridEh1.Columns[4].Footer.SumValue]));


Кстати вырисовалась дополнительно еще одна загвоздка. DBGridEh1.Columns[4].Footer.SumValue Имеет тип Variant и при применении параметра %.0f Тоже выдает ошибку несовместимости типа параметра, хотя в таблице поле имеет тип Double.


 
Ega23 ©   (2011-10-18 16:20) [8]

Ты не используешь параметры.
Используй их и будет тебе щщасте.


 
OW ©   (2011-10-18 16:21) [9]

uses the parameters
verwendet die Parameter
utilise les paramètres
パラメータを使用して います


 
OW ©   (2011-10-18 16:31) [10]

кажется, уловил мысль
вот, не претендуя на изящество и опуская проверки

procedure OpenQ(const Q:TORA(или ADO)Query; const SQL:string; const P:array of variant);
var
 i:integer;
 s:string;
begin
 try
 try
   Screen.Cursor := crHourGlass;
   if SQL <> "" then
        Q.SQL.Text := SQL;
   s := "";
   for i := 0 to Q.ParamCount-1 do
   begin
     case Q.Params[i].DataType of
       ftDateTime: Q.Params[i].AsDateTime := P[i];
       else Q.Params[i].Value := P[i];
     end;
     s := s + Q.Params[i].Name + "=" + Q.Params[i].AsString + #13#10;
   end;
   Q.Open;
 except
   on E:Exception do
   begin
     Screen.Cursor := crDefault;
     E.Message := E.Message + #13#10 + "досада в uUtils. procedure OpenQ. при попытке сделать " + #13#10 + Q.SQL.Text + #13#10 + " а параметры таковы:" + s;
     Raise;
   end;
 end;
 Screen.Cursor := crDefault;
end;

 OpenQ(oqTmp, "select * from AGENTS where ID_AGENT = :ID_AGENT ", [IdAgent]);
 FAgentId := oqTmp.FieldbyName("ID_AGENT").Value;


 
Laguna ©   (2011-10-18 16:32) [11]

Я понял насчет параметров, как единичный случай сейчас попробую. Только как это будет выглядеть с применением их в общей процедуре? Параметры я указываю после строки запроса. А ведь их(параметров) каждый раз может быть различное количество. В данной ситуации Format ведь тоже использует параметры и все в одной строке.


 
Ega23 ©   (2011-10-18 16:34) [12]


> Только как это будет выглядеть с применением их в общей
> процедуре?


А не надо общую процедуру делать. Незачем.


 
OW ©   (2011-10-18 16:54) [13]


> не надо общую процедуру делать. Незачем.

да можно,
для упрощения, например

OpenQ(oqTmp, "select * from ТАБЛА1 where ID_COL = :ID_COL ", [AVal]);
FMyVar1 := oqTmp.FieldbyName("COL_NAME").Value;
OpenQ(oqTmp, "select * from ТАБЛА22 where ID_COL = :ID_COL and ID_COL2 = :ID_COL2 ", [AVal2, AVal3]);
FMyVar2 := oqTmp.FieldbyName("COL_SUBSCRIBE").Value;

вместо

oqTmp.sql.test := "select * from ТАБЛА1 where ID_COL = :ID_COL ";
oqTmp.pameters.parambyname(). value := AVal;
oqTmp.Open;
FMyVar1 := oqTmp.FieldbyName("COL_NAME").Value;
oqTmp.sql.test := "select * from ТАБЛА22 where ID_COL = :ID_COL and ID_COL2 = :ID_COL2 ";
oqTmp.pameters.parambyname(). value := AVal2;
oqTmp.pameters.parambyname(). value := AVal3;
oqTmp.Open;
FMyVar2 := oqTmp.FieldbyName("COL_SUBSCRIBE").Value;

представляется вот это все
oqTmp.pameters.parambyname(). value := AVal2;
oqTmp.pameters.parambyname(). value := AVal3;
да и Open|Exec потом - шелуха, детали, отвлекающие от сути

запрос и сразу параметры - имхо, лучше.


 
Ega23 ©   (2011-10-18 16:59) [14]


> да можно,
> для упрощения, например


Про упрощение - спорное утверждение.
Это запутывание + реинициализация CommandText и списка параметров при каждом вызове.
В принципе, иметь такую функцию, наверное полезно. Но пользоваться ей направо и налево я бы не стал.


 
Laguna ©   (2011-10-18 17:07) [15]

>Ega23

Почему же не нужна общая процедура? Это в данном случае так получилось, что дату никак не прикрутить, кроме как через параметры. А так она много где используется, как принимающая уже подготовленную строку запрса.


 
OW ©   (2011-10-18 17:07) [16]


> Это запутывание

нет, почему?
Tmp - временная ерунда, для считать по мелочи данные из БД,
что-то серьёзное - достойно самостоятельного компонента на форме/модуле
но, и к нему тоже можно применить!

procedure OpenQ(const Q:TORA(или ADO)Query; const SQL:string; const P:array of variant);
var
i:integer;
s:string;
begin
try
try
  Screen.Cursor := crHourGlass;
  if SQL <> "" then
       Q.SQL.Text := SQL;


т.е.
OpenQ(oqTmp, "", [Val]);
и нет никакой
>> реинициализация CommandText и списка параметров при каждом вызове.


 
Laguna ©   (2011-10-18 17:17) [17]

Я подумал что будет загвозда в передаче параметров. Ан нет, действительно можно в качестве массива из Variant


 
Ega23 ©   (2011-10-18 17:20) [18]


> А так она много где используется, как принимающая уже подготовленную
> строку запрса.


Так ты и давай строку запроса, а потом меняй значение параметра. Нафига при каждом изменении значения параметра реинициализировать всё?


> и нет никакой
> >> реинициализация CommandText и списка параметров при каждом
> вызове.


Я не знаю, как DOA себя ведёт. Но крайне рекомендую поиграться с ADO. Как с канонiчным, так и с дельфёвой реализацией.
Хотя чё там играться-то, см. TADODataSet.CommandText


 
OW ©   (2011-10-18 17:24) [19]

да говорю же

OpenQ(aqTmp, "", [Val]); или OpenQ(oqTmp, "", [Val]);
тут SQL = ""
а в этом случае Q.SQL.Text не меняется, ничего не происходит ни с командой, ни, соответственно, с параметрами, настроенными вдруг до этого, так или иначе.


 
Ega23 ©   (2011-10-18 17:29) [20]


> ни, соответственно, с параметрами, настроенными вдруг до
> этого, так или иначе.


Не знаю. ИМХО, всё равно фигня полная. BLOB не передать толком, для даты-время - отдельная строчка. Строка и число? Да и по имени параметра толком не обратишься.
ИМХО - ацтой, только путает.
Вот если через атрибуты RTTI как-то попробовать завязаться - это уже совсем другое дело.


 
OW ©   (2011-10-18 17:45) [21]


> для даты-время - отдельная строчка

да, это атавизм, это из-за того что в проекте юзал неподготовленную в параметрах DS. А если подготовленная, то и не надо этой строчки.


> BLOB не передать толком

не передать. Тут "честно" надо.
В остальном юзается нормально пока.


> Строка и число?

не понял


> Да и по имени параметра толком не обратишься

можно, если обычно опять же писать.

Это способ, повторюсь, для того что бы не загромождать код всякими
парам = значение
парам = значение
парам = значение
открыть
когда читаем что-то рабочее, малозначительное. Зачем место тратить..


 
Laguna ©   (2011-10-18 17:50) [22]

Сделал вот так

procedure SqlFromTab(St : String; const P : array of variant);
Var
 i : Integer;
begin
 with TADOQuery.Create(nil) do
  try
    ADOConnection := DM1.AdoConnection1;
    ParamCheck := True;
    SQL.Clear;
    for i := 0 to High(P) do
     Params[i].Value := P[i];
    SQL.Add(St);
    ExecSQL;
  finally
    Free;
  end;
end;


В программе запускаю процедуру

         SqlFromTab("Insert InTo OperTab (RegKod, DataDoc, NameDoc, SumDoc) Values (:p1, :p2, :p3, :p4)",
                        [RegInf.Kod, DataDocDateEdit.Date, NameDocEdit.Text,
                         DBGridEh1.Columns[4].Footer.SumValue]);


В отладку смотрю - массив заполнен, но Params[i].Value := P[i]; вылетает ошибка List Index Out of Bonds. В момент трассировки P[i] AV. В чем дело? Что опять не так?


 
Медвежонок Пятачок ©   (2011-10-18 18:02) [23]

параметров запроса меньше чем длина массива


 
Ega23 ©   (2011-10-18 19:02) [24]


> В чем дело? Что опять не так?


Вот об этом, Влад, я и писал.

> Это способ, повторюсь, для того что бы не загромождать код всякими


Не захотел поциэнт "загромождать код всякими" - теперь любится до усёру.

З.Ы. А я ещё более параноидально с некоторых пор предпочитаю делать. Я и ParamCheck в False ставлю, а параметры с их типами добавляю исключительно вручную.


 
Плохиш ©   (2011-10-18 20:21) [25]


> параметров запроса меньше чем длина массива

На момент присваивания их вообще нет, да и запроса никакого нет.

> Laguna ©   (18.10.11 17:50) [22]

Ты б с бумажкой и карандашом перошёлся по своему "коду", да выполни его сам.


 
Игорь Шевченко ©   (2011-10-18 20:38) [26]


> f = Установленный
> g = Генерал


Это что и откуда ?


 
Laguna ©   (2011-10-18 21:02) [27]

> Игорь Шевченко

> f = Установленный
> g = Генерал

Это что и откуда ?


http://www.delphibasics.ru/Format.php

точка останова for i := 0 to High(P) do - массив содержит 4 элемента


 
Игорь Шевченко ©   (2011-10-18 21:25) [28]


> http://www.delphibasics.ru/Format.php


Внушает.

"&#212;&#243;&#237;&#234;&#246;&#232;&#255; Format &#238;&#225;&#229;&#241;&#239;&#229;&#247;&#232;&#226;&#224;&#229;&#803; "C" &#239;&#238;&#228;&#238;&#225;&#237;&#238;&#229; &#244;&#238;&#273;&#769;&#224;&#803;&#232;&#273;&#238;&#226;&#224;&#237;&#232;&# 229; &#769;&#237;&#238;&#230;&#229;&#241;&#803;&#226;&#224; &#239;&#273;&#238;&#241;&#803;&#251;&#417; &#803;&#232;&#239;&#238;&#226; &#228;&#224;&#237;&#237;&#251;&#417; &#226; &#241;&#803;&#273;&#238;&#234;&#229;. &#206;&#237;&#224; &#238;&#225;&#229;&#241;&#239;&#229;&#247;&#232;&#226;&#224;&#229;&#803; &#238;&#247;&#229;&#237;&#252; &#803;&#238;&#247;&#237;&#238;&#229; &#243;&#239;&#273;&#224;&#226;&#235;&#229;&#237;&#232;&#229; &#239;&#238; &#432;&#803;&#238;&#769;&#243; &#244;&#238;&#273;&#769;&#224;&#803;&#232;&#273;&#238;&#226;&#224;&#237;&#232;&# 8363;.

d = &#196;&#229;&#241;&#255;&#803;&#232;&#247;&#237;&#238;&#229; (&#246;&#229;&#235;&#238;&#229; &#247;&#232;&#241;&#235;&#238;)
e = &#205;&#224;&#243;&#247;&#237;&#251;&#233;
f = &#211;&#241;&#803;&#224;&#237;&#238;&#226;&#235;&#229;&#237;&#237;&#251;&#233;
g = &#258;&#229;&#237;&#229;&#273;&#224;&#235;
m = &#196;&#229;&#237;&#252;&#259;&#232;
n = &#215;&#232;&#241;&#235;&#238; (&#239;&#235;&#224;&#226;&#224;&#8363;&#249;&#229;&#229;)
p = &#211;&#234;&#224;&#231;&#224;&#803;&#229;&#235;&#252;
s = &#209;&#803;&#273;&#238;&#234;&#224;
u = &#196;&#229;&#241;&#255;&#803;&#232;&#247;&#237;&#238;&#229; &#247;&#232;&#241;&#235;&#238; &#225;&#229;&#231; &#231;&#237;&#224;&#234;&#224;
x = &#216;&#229;&#241;&#803;&#237;&#224;&#228;&#246;&#224;&#803;&#229;&#273;&#232;&# 247;&#237;&#251;&#233; "


 
Плохиш ©   (2011-10-18 21:29) [29]


> Laguna ©   (18.10.11 21:02) [27]

> точка останова for i := 0 to High(P) do - массив содержит
> 4 элемента

Какой из двух?


 
Ega23 ©   (2011-10-18 21:45) [30]


> Какой из двух?


Да не из двух. Товарищ SQL.Clear делает, а потом удивляется.


 
Laguna ©   (2011-10-18 23:56) [31]

Допустим Clear я делаю всегда перед подстановкой новой строки запроса. Другое дело , что "настроку параметров" я выполняю не в том месте,

 SQL.Clear;
 for i := 0 to High(P) do
   Params[i].Value := P[i];
 SQL.Add(St);
 ExecSQL;

А нужно правильно так, ИМХО

 SQL.Clear;
 SQL.Add(St);
 for i := 0 to High(P) do
   Params[i].Value := P[i];
 ExecSQL;


по крайней мере  когда подставлю реальные параметрвы типа
парам = значение
парам = значение
парам = значение


 
Laguna ©   (2011-10-19 00:37) [32]

НУ, как я и предполагал, неверно было расположено место присвоения значений параметрам. После внесения изменений все заработало ка нужно. Вот конечный вариант многовариантной процедуры :

procedure OperFromBuhTab(St : String; const P : array of variant);
Var
 i : Integer;
begin
 with TADOQuery.Create(nil) do
  try
    ADOConnection := DM1.AdoConnection1;
    ParamCheck := True;
    SQL.Clear;
    SQL.Add(St);
    for i := 0 to High(P) do
     Params[i].Value := P[i];
    ExecSQL;
  finally
    Free;
  end;
end;


Преимущества использования этой процедуры:
1) Query коспонент формируется в рантайм по мере необходимости
2) Произвольное количество входящих параметров

OW - спасибо за const P : array of variant
Ega23 - спасибо за Товарищ SQL.Clear делает, а потом удивляется. Хоть не совсем то, но навело на мысль обратить внимание на место расположения строки запроса и параметров.


 
Германн ©   (2011-10-19 01:20) [33]


> Laguna ©   (18.10.11 23:56) [31]
>
> Допустим Clear я делаю всегда перед подстановкой новой строки
> запроса. Другое дело , что "настроку параметров" я выполняю
> не в том месте,

???
Очень похоже на "револьвер". И на "русскую рулетку". :)


 
Ega23 ©   (2011-10-19 01:26) [34]


> Преимущества использования этой процедуры:


Недостатки данной процедуры:
1. Не SQl.Add(St), а SQL.Text := St;
2. Не TADOQuery, а TADOCommand.
3. Либо for i := 0 to Length(P) - 1 do, либо for i:= Low(P) to High(P) do
4. ИМХО, самое главное: работа с BLOB-ом не учтена.
5. Каждый раз создаётся экземпляр TADOQuery. По-хорошему, надо одну такую держать для "разовых" работ. Как вариант - ввести её параметром, если <> nil, то работать с ней, если = nil, то создавать и убивать.
6. Привязка к конкретному экземпляру TADOConnection. Коль делаешь универсальную процедуру - будь любезен делать её универсальной, не зависящей от всяких конкретных DataModule.

Как-то так.


 
Ega23 ©   (2011-10-19 01:27) [35]

З.Ы. Перед SQL.Clear тут вообще лишнее. Если Add на Text заменить, конечно.


 
OW ©   (2011-10-19 08:46) [36]


> 6. Привязка к конкретному экземпляру TADOConnection. Коль
> делаешь универсальную процедуру - будь любезен делать её
> универсальной, не зависящей от всяких конкретных DataModule.

+

насчет:

> Каждый раз создаётся экземпляр TADOQuery. По-хорошему, надо
> одну такую держать для "разовых" работ. Как вариант - ввести
> её параметром, если <> nil, то работать с ней, если = nil,
>  то создавать и убивать.
>


тоже думал..  может, класс завести.. С учетом 6:
например,
RunnerQ.Connection := бла-бла1
RunnerQ.OpenQ()
RunnerQ.ExecQ()
RunnerQ.FConnection := бла-бла2
RunnerQ.OpenQ()
и т.п.

А насчет,

> Не захотел поциэнт "загромождать код всякими" - теперь любится
> до усёру.

так: пациент и не хочет слушать, походу. Или хочет выборочно.
ну и ССЗБ, чего сказать :)


 
Anatoly Podgoretsky ©   (2011-10-19 09:14) [37]


> 2. Не TADOQuery, а TADOCommand.

х. И не Params, а Parameters

И вообще переписать все нафиг


 
Laguna ©   (2011-10-19 09:15) [38]

> Недостатки данной процедуры:
>1. Не SQl.Add(St), а SQL.Text
Есть принципиальная разница, что строго Text нужно применять?

> := St;2. Не TADOQuery, а TADOCommand.3. Либо for i := 0
> to Length(P) - 1 do, либо for i:= Low(P) to High(P) do4.
а Length(P) - 1 и High(P) не даст одно и то же для конечного параметра цикла?

>  ИМХО, самое главное: работа с BLOB-ом не учтена.
Согласен. В данный момент небыло необходимости, но...

> Каждый раз создаётся экземпляр TADOQuery.
Да, есть такое дело. Ноэта процедура не используется в цикле. Для разовых операций(удалить записи, добавить запист и т.д)

> По-хорошему, надо одну такую держать для "разовых" работ. Как вариант >- ввести  её параметром, если <> nil, то работать с ней, если = nil,
>  то создавать и убивать.
Раньше так и делал. Решил разнообразить.

> Привязка к конкретному экземпляру TADOConnection. Коль делаешь
> универсальную процедуру - будь любезен делать её универсальной, не >зависящей от всяких конкретных DataModule.Как-то так.
Согласен, нужно думать.


> так: пациент и не хочет слушать, походу. Или хочет выборочно.
>  ну и ССЗБ, чего сказать :)

Не совсем разобрался на что конкретно нужно было усилить внимание.


 
Laguna ©   (2011-10-19 09:19) [39]

Забыл дописать, SQL.Clear; в данной процедуре действительно совершенно не нужен. Спасибо.


 
Ega23 ©   (2011-10-19 10:24) [40]


> Есть принципиальная разница, что строго Text нужно применять?


В твоём конкретном примере - нет. Вообще - есть, и довольно серьёзная.
constructor TADOQuery.Create(AOwner: TComponent);
begin
 inherited Create(AOwner);
 FSQL := TStringList.Create;
 TStringList(FSQL).OnChange := QueryChanged;
 Command.CommandTextAlias := "SQL"; { Do not localize }
end;



> а Length(P) - 1 и High(P) не даст одно и то же для конечного параметра цикла?


В твоём конкретном случае - даст. В общем - нет.


> Согласен, нужно думать.


На самом деле тут всё просто.
Либо делаешь полностью универсальную процедуру, подаёшь в неё Connection, текст запроса и параметры.
Либо делаешь паблик-метод своего датамодуля и в нём уже используешь один и тот же TADOCommand. Т.е. просто текст запроса и параметры.
Либо (но этот вариант для D7 не прокатит) делаешь class helper для того же TADOCommand



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2012.01.29;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.006 c
1-1282384267
MSV
2010-08-21 13:51
2012.01.29
Двустрорнняя печать


2-1318669158
Тима12
2011-10-15 12:59
2012.01.29
Отладка программы


1-1282634224
Дмитрий Белькевич
2010-08-24 11:17
2012.01.29
TJvDBTreeView, хинт (ToolTips) обрезается до 80-ти символов.


15-1318019402
Юрий
2011-10-08 00:30
2012.01.29
С днем рождения ! 8 октября 2011 суббота


15-1318241847
Demo
2011-10-10 14:17
2012.01.29
ПО для терминалов





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский