![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Создать таблицу на основе SQL запроса [D7]
Devmaster © (2005-11-21 12:38:00)необходимо создать таблицу на основании даных из SQL запроса
делаю так:
begin
OraSession.Connected:= True;
qTemp.Close;
qTemp.SQL.Text:= 'select kod_xxx kod,st_name name from xx';
qTemp.Open;
tPredpr.Close;
qTemp.First;
//копирую структуру полей
tPredpr.FieldDefs:= qTemp.FieldDefs;
tPredpr.Active:= True;
//копирую все данные - КАК ЭТО СДЕЛАТЬ ПОДРУГОМУ
типа того как я скопировал структуру?
while not qTemp.Eof do
begin
tPredpr.Insert;
tPredpr.fields[0].Value:= qTemp.Fields[0].Value;
tPredpr.fields[1].Value:= qTemp.Fields[1].Value;
tPredpr.Post;
qTemp.Next;
end;
end;
Juice (2005-11-22 11:02:00) [1]Может тебя это устроит ? -
ClientDataSet1.Data := ClientDataSet2.Data
Devmaster (2005-11-21 16:51:00) [2]
> ANB © (21.11.05 15:57) [15]
>
> > Devmaster (21.11.05 15:33) [12]
>
> В таком стиле - нету. В каком то виртуальном дейтасете есть
> метод CopyFromDataSet, но тут уже жаловались, что он криво
> работает. А проблем то : пройтись в цикле по НД источнику
> и переложить данные в приемник. Пример у тебя перед глазами.
> Кстати, ща могу глянуть и для запросов.
Вот это и нужно было. Всем спасибо.
ANB (2005-11-21 16:28:00) [3]
function Save_SQL(AParam : array of String; fmLog : TfmLog;
var SessionList : TSessionList;
sStepName, Expression : String) : String;
var sVarName, sSessionName, sSchema, sData, sErrors : String;
Session : TOraSession;
qrSQL : TOraQuery;
vtData : TVirtualTable;
smData : TStream;
i, n : Integer;
bStopSQL : Boolean;
begin
Result := '';
// Качнем параметры
sSessionName := ClearVarName(AParam[0]);
sVarName := ClearVarName(AParam[1]);
// Найдем или добавим нужную кверю
qrSQL := TOraQuery.Create(nil);
vtData := TVirtualTable.Create(nil);
smData := TMemoryStream.Create;
try
// Найдем или добавим нужную сессию
Session :=FindSession(sSessionName, SessionList, LocalParam,
sStepName, Global_Error);
if (Session.Connected) then begin
// Если сессия открылась
// Достанем схему
sSchema := ClearVarName(GetVariable(sSessionName + '#Schema'));
sErrors := ExecutePLSQLASync(Session, Expression, sSchema, fmLog, bStopSQL, qrSQL);
// Выполнено с ошибкой или прервано пользователем
if (Length(sErrors) > 0) then begin
Result := sErrors;
Exit;
end;
if (qrSQL <> nil) then begin
// Сохраним из него результат
n := qrSQL.FieldCount - 1;
vtData.Close;
vtData.Clear;
vtData.DeleteFields;
for i := 0 to n do begin
if (qrSQL.Fields[i].DataType = ftString)
then vtData.AddField(qrSQL.Fields[i].FieldName, ftString,
max(qrSQL.Fields[i].DataSize, 30))
else vtData.AddField(qrSQL.Fields[i].FieldName, ftString, 30);
end;
// Качнем данные
vtData.Open;
while (not qrSQL.Eof) do begin
vtData.Append;
for i := 0 to n do begin
vtData.Fields[i].AsString := qrSQL.Fields[i].AsString;
end;
vtData.Post;
qrSQL.Next;
end;
// Закроем запрос
qrSQL.Close;
// Сохраним в поток
vtData.SaveToStream(smData);
vtData.Close;
// Перепишем в строку
i := smData.Size;
SetLength(sData, i + 1);
smData.Seek(0, 0);
smData.Read(sData[1], i);
SetVariable(sVarName, sData, 1);
end;
end else begin
// Сессия не открылась
Result := Global_Error;
end;
finally
if (qrSQL <> nil) then qrSQL.Close;
if (vtData <> nil) then vtData.Close;
if (qrSQL <> nil) then FreeAndNil(qrSQL);
if (vtData <> nil) then FreeAndNil(vtData);
if (smData <> nil) then FreeAndNil(smData);
end;
end;
Тут я, правда вообще в строку НД загоняю. Лишнее выкинешь.
evvcom (2005-11-21 16:00:00) [4]
> Кстати, ща могу глянуть и для запросов
А чего там глядеть, DataSet он и в африке DataSet! Главное, сделать его редактируемым, остальное аналогично.
ANB (2005-11-21 15:57:00) [5]
> Devmaster (21.11.05 15:33) [12]
В таком стиле - нету. В каком то виртуальном дейтасете есть метод CopyFromDataSet, но тут уже жаловались, что он криво работает. А проблем то : пройтись в цикле по НД источнику и переложить данные в приемник. Пример у тебя перед глазами. Кстати, ща могу глянуть и для запросов.
evvcom (2005-11-21 15:40:00) [6]FieldDefs насколько я помню это класс. В нем реализовано что-то типа
for i:=0 to FieldCount - 1 do ...
Реализуй аналогичное у себя. В чем проблемы? Там писать гораздо меньше, чем тут настукивать вопросы по клаве.
Sergey13 (2005-11-21 15:37:00) [7]2[12] Devmaster (21.11.05 15:33)
> смысл один КАК СКОПИРОВАТЬ ДАНЫЕ С ОДНОГО НАБОРА В ДРУГОЙ БЕЗ ИСПОЛЬЗОВАНИЯ SQL.
Теперь перечитай свой вопрос
>необходимо создать таблицу на основании даных из SQL запроса
И сравни.
Devmaster (2005-11-21 15:33:00) [8]Извините за мою грубость, но если я буду рассказывать что я хочу сделать - пальцы заболят стукать по клаве:))
для ANB
один набор на сервере а другой локально! целостность не нарушится!
> >Это прога по 1 разовому залитию в месяц, файла на сервер
> Вот уже и файлы внешние появились. Ты из него SQL-ем читаешь?
> Каким образом?
ну и что что появились ! - смысл один КАК СКОПИРОВАТЬ ДАНЫЕ С ОДНОГО НАБОРА В ДРУГОЙ БЕЗ ИСПОЛЬЗОВАНИЯ SQL.
ребята, копирование структуры - tPredpr.FieldDefs:= qTemp.FieldDefs
есть чтото в таком стиле для переноса данных?
Devmaster (2005-11-21 15:28:00) [9]один набор на сервере а другой локально! целостность не нарушится!
ребята, копирование структуры - tPredpr.FieldDefs:= qTemp.FieldDefs
есть чтото в таком стиле для переноса данных?
Desdechado (2005-11-21 15:17:00) [10]без постановки задачи решения не бывает
если не уважаешь собеседника(ов), ответов не жди
Sergey13 (2005-11-21 15:05:00) [11]2[6] Devmaster (21.11.05 14:36)
> Я спросил как перенести даные из 1 набора в 2!
Если оба набора уже в БД, то это безсмысенно в большинстве случаев.
>ты когда у людей спрашиваеш как пройти на такую-то улицу у тебя тоже спрашивают зачем?
Тут часто спрашивают подобное. Потом оказывается, что они вообще в другом городе находятся, и тут на той улице только морг. 8-)
>А то что ты считаеш мне до одного места!
Это ради бога. Не возражаю. 8-)
>Спрашиваеш зачем использовать SQL а сам пишеш SQL!
Ну и что? Я же говорил не о невозможности этого.
>Это прога по 1 разовому залитию в месяц, файла на сервер
Вот уже и файлы внешние появились. Ты из него SQL-ем читаешь? Каким образом?
ANB (2005-11-21 14:51:00) [12]
> Devmaster (21.11.05 14:36) [6]
Грубите, молодой человек, мастерам. Да еще и инкогнито.
ANB (2005-11-21 14:42:00) [13]
> evvcom © (21.11.05 14:02) [5]
Если все складывать в нормальные локальные таблицы то это не самая главная проблема.
> Devmaster (21.11.05 13:28) [3]
1. Как собираешься контролировать ссылочную целостность ? (Справочники на сервере могут за день поправить и вся работа за день - на смарку).
2. Почему долго идет запись ? Сервер удаленный и канал тонкий ? Так АП уже писал системы с тонким каналом и все равно у него все шустро работало.
3. Если нужно сделать копию набора данных в TVirtualTable, то могу положить как пример копирование листа Excel :
unit Excel_Utils_U;
interface
uses
Types, SysUtils, StrUtils,
Variants,
ComObj,
DB, Ora, VirtualTable;
function ExcelToVirtualTable(FileName : String; var VirtualTable : TVirtualTable;
Area : TRect) : String;
implementation
function ExcelToVirtualTable(FileName : String; var VirtualTable : TVirtualTable;
Area : TRect) : String;
var ApplicationName : String;
ExcelApplication : Variant;
FieldNo, RowNo : Integer;
FieldName : String;
CellValue : String;
Errors : String;
begin
Result := '';
Errors := '';
// Заготовим поля в VirtualTable
VirtualTable.Close;
VirtualTable.Clear;
VirtualTable.Fields.Clear;
VirtualTable.FieldDefs.Clear;
for FieldNo := Area.Left to Area.Right do begin
FieldName := 'F' + IntToStr(FieldNo);
VirtualTable.AddField(FieldName, ftString, 1024, False);
end;
VirtualTable.Open;
// Запустим копию Excel
ApplicationName := 'Excel.Application';
ExcelApplication := Null;
try
ExcelApplication := CreateOleObject(ApplicationName);
except
on E : Exception do begin
Result := 'Ошибка при создании экземпляра Excel : ' + E.Message;
Exit;
end;
end;
try
try
// Сделаем Excel невидимым
ExcelApplication.Visible := False;
ExcelApplication.DisplayAlerts := False;
// Откроем таблицу
ExcelApplication.WorkBooks.Open(FileName);
// Прогуляемся по таблице и перекачаем данные в VirtualTable
for RowNo := Area.Top to Area.Bottom do begin
VirtualTable.Append;
for FieldNo := Area.Left to Area.Right do begin
FieldName := 'F' + IntToStr(FieldNo);
CellValue := '';
// 'ComTrn'
try
CellValue := ExcelApplication.WorkBooks[1].WorkSheets[1].Cells[RowNo, FieldNo].Value;
except
on E : Exception do begin
Errors := Errors
+ 'Ошибка при получении ячейки ['+IntToStr(RowNo)+', '+IntToStr(FieldNo)+'] : '
+ E.Message
+ #13#10;
end;
end;
VirtualTable.FieldByName(FieldName).AsString := CellValue;
end;
VirtualTable.Post;
end;
VirtualTable.First;
except
on E : Exception do begin
Errors := Errors
+ 'Ошибка при получении данных : '
+ E.Message
+ #13#10;
end;
end;
finally
// Закроем копию Excel
ExcelApplication.Workbooks[1].Close;
ExcelApplication.Quit;
ExcelApplication := Unassigned;
// Вернем ответ
if Length(Errors) > 0 then Result := Errors;
end;
end;
end.
Devmaster (2005-11-21 14:36:00) [14]
> Sergey13 © (21.11.05 13:34) [4]
> 2 [3] Devmaster (21.11.05 13:28)
> Пока не объяснишь что ты пытаешься сделать я буду считать
> твою схему работы неудачной (это я очень мягко сказал 8-
> ).
Я спросил как перенести даные из 1 набора в 2!
ты когда у людей спрашиваеш как пройти на такую-то улицу у тебя тоже спрашивают зачем? А то что ты считаеш мне до одного места!
> Sergey13 © (21.11.05 12:42) [2]
> 1. А зачем вообще создавать таблицу на основе SQL запроса?
>
> 2. Зачем это делать так? Достаточно Create Table Table_name
> as Select
Спрашиваеш зачем использовать SQL а сам пишеш SQL!
> evvcom © (21.11.05 14:02) [5]
>
> > Дело в том что запись на сервер очень долго идет и пользователь
>
> > НЕРВНИЧАЕТ! а так в конце работы нажал кнопочку и все
> там!
>
> А прикинь, как будет "нервничать" пользователь, если вдруг
> компьютер глюкнет, и все результаты его работы за день пропадут?
> Я думаю, живым ты домой не уйдешь.
Это прога по 1 разовому залитию в месяц, файла на сервер, причем с проверкой каждого параметра(постояно спрашивать у базы есть ли такое...)
Так вот скорость работы увеличилась ~ в 5 раз ...
evvcom (2005-11-21 14:02:00) [15]
> Дело в том что запись на сервер очень долго идет и пользователь
> НЕРВНИЧАЕТ! а так в конце работы нажал кнопочку и все там!
А прикинь, как будет "нервничать" пользователь, если вдруг компьютер глюкнет, и все результаты его работы за день пропадут? Я думаю, живым ты домой не уйдешь.
Sergey13 (2005-11-21 13:34:00) [16]2 [3] Devmaster (21.11.05 13:28)
Пока не объяснишь что ты пытаешься сделать я буду считать твою схему работы неудачной (это я оченьмягко сказал 8-).
Devmaster (2005-11-21 13:28:00) [17]to ANB - tPredp - vTirtualTable - SQL не поддерживает! и создать нужно локально а не на сервере.
to Sergey13
> 1. А зачем вообще создавать таблицу на основе SQL запроса?
в начале работы приложения загрузить все в нее! потом во время работы вносить новые данные(до 100000 записей) а в конце закинуть на сервак - вот как пока думаю возможно XML или както упакую!
Дело в том что запись на сервер очень долго идет и пользователь НЕРВНИЧАЕТ! а так в конце работы нажал кнопочку и все там!
Данные паралельно используют только для просмотра!
ANB (2005-11-21 12:42:00) [18]create table Table1 as select * from . . .
Sergey13 (2005-11-21 12:42:00) [19]1. А зачем вообще создавать таблицу на основе SQL запроса?
2. Зачем это делать так? Достаточно Create Table Table_name as Select ....