Форум: "Начинающим";
Текущий архив: 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
Внушает.
"Ôóíêöèÿ Format îáåñïå÷èâàạ̊ "C" ïîäîáíîå ôîđ́ạ̀èđîâàíè&# 229; ́íîæåṇ̃âà ïđîṇ̃ûơ ̣èïîâ äàííûơ â ṇ̃đîêå. Îíà îáåñïå÷èâàạ̊ î÷åíü ̣î÷íîå óïđàâëåíèå ïî ựî́ó ôîđ́ạ̀èđîâàíè&# 8363;.
d = Äåñỵ̈è÷íîå (öåëîå ÷èñëî)
e = Íàó÷íûé
f = Óṇ̃àíîâëåííûé
g = Ăåíåđàë
m = Äåíüăè
n = ×èñëî (ïëàâà₫ùåå)
p = Óêàçạ̀åëü
s = Ṇ̃đîêà
u = Äåñỵ̈è÷íîå ÷èñëî áåç çíàêà
x = Øåṇ̃íàäöạ̀åđè&# 247;íûé "
← →
Плохиш © (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