Форум: "Базы";
Текущий архив: 2004.04.04;
Скачать: [xml.tar.bz2];
ВнизКак передать хранимой процедуре одиночные параметры + DataSet ? Найти похожие ветки
← →
BPK (2004-03-10 14:47) [0]Имеются:
1. MS SQL Server 2000
2. хранимая процедура со входными параметрами
3. Delphi + ADO
Текущее состояние дел:
В клиентском приложении, написанном на Delphi, вызывается упомянутая хранимая процедура.
Ей передаём набор одиночных параметров, взятых из полей структуры (record).
ХП записывает эти поля в таблицу.
Требуется:
К структуре добавляем дополнительное поле - список (кто хочет, может считать, что это DataSet).
Этот список - тоже один из атрибутов объекта, описываемого данной структурой, и его тоже нужно записывать, но в другую таблицу со ссылками на первую.
Как передать на вход хранимой процедуры одновременно и набор одиночных параметров, и этот список?
Единственное плохое решение, пришедшее мне на ум:
Сделать дополнительную хранимую процедуру, заполняющую этот список, и вызывать её сразу после основной ХП.
Чем плохо такое решение:
В промежутке между вызовами БД может быть изменена, приложение зависнет, рухнет сеть, и т.п.
В результате БД расползётся.
Нужно обязательно делать всё за одну транзакцию.
← →
Delirium © (2004-03-10 14:54) [1]http://delphibase.endimus.com/
← →
Reindeer Moss Eater © (2004-03-10 15:00) [2]А кто сказал, что два и более вызова хранимых процедур не могут идти в одной транзакции?
← →
Polevi © (2004-03-10 15:02) [3]передавай xml данные ntext параметром
в процедуре используй sp_xml_preparedocument, sp_xml_removedocument и FOR XML запросы
← →
Reindeer Moss Eater © (2004-03-10 15:02) [4]К структуре добавляем дополнительное поле - список (кто хочет, может считать, что это DataSet).
Этот датасет как-то оказался на клиенте. Значит был запрос к БД.
Почему этот датасет надо тянуть на клиента что бы потом передать взад на сервер хранимой процедуре?
Что, разве нельзя открыть курсор прямо в первой sp?
← →
BPK (2004-03-10 15:03) [5]>А кто сказал, что два и более вызова хранимых процедур не могут идти в одной транзакции?
А как? В смысле, как организовать транзакцию из приложения Delphi?
P.S.
Обратите внимание, что поле списка в record"е это указатель на объект-список, из к-рого мы формируем ОТДЕЛЬНЫЙ DataSet или что-нибудь подобное.
← →
Polevi © (2004-03-10 15:04) [6]>Reindeer Moss Eater © (10.03.04 15:02) [4]
может это добавленные юзером данные
← →
Polevi © (2004-03-10 15:05) [7]>BPK (10.03.04 15:03) [5]
я тебе дело говорю, используй xml
один параметр в процедуре будет, не придется в будущем ничего трогать
но возможно ты еще не готов
← →
Delirium © (2004-03-10 15:06) [8]> BPK (10.03.04 15:03) [5]
Надо делать так, как сказал Polevi © (10.03.04 15:02) [3], готовая реализация на http://delphibase.endimus.com/, чего ещё?
← →
BPK (2004-03-10 15:06) [9]>Этот датасет как-то оказался на клиенте. Значит был запрос к БД.
Нет. Мы его сами сформировали. Ну хорошо, не DataSet, а динамический массив, а вернее объект-хранилище, а то я вижу, что у Вас слово DataSet железно ассоциируется с базами данных.
← →
Delirium © (2004-03-10 15:12) [10]"Вас слово DataSet железно ассоциируется с базами данных" - да ничего у нас не ассоциируется, я вижу ты даже представить себе не можешь, что твоя проблемя уже давным-давно решена, одно из решений http://delphibase.endimus.com/?action=viewfunc&topic=basemssql&id=10400, по нему есть вопросы?
← →
BPK (2004-03-10 15:17) [11]>по нему есть вопросы?
Mamma mia! Ну что, попытаюсь в этом разобраться.
Спасибо.
Если это не поможет, или не разберусь ;-) , то сформирую string, а в ХП сделаю анализ этого string.
← →
Nikolay M. © (2004-03-10 15:19) [12]Если пугает XML, можно еще через временные таблицы.
← →
Delirium © (2004-03-10 15:21) [13]"Если это не поможет" - значит не разобрался.
← →
ZrenBy © (2004-03-10 15:38) [14]Можно проще, если сам себе хозяин
...
AssignFile(tfXML,FileXML);
ReWrite(tfXML);
Write(tfXML,"<?xml version="1.0" encoding="windows-1251"?>");
Write(tfXML,"<ROOT>");
for n:=1 to Count do begin
Write(tfXML,"<DS"+
" A="" + IntToStr(n) +"""+
" B="" + MyArray[n].B +"""+
" C="" + IntToStr(MyArray[n].C) +"""+
"/>"
);
end;
Write(tfXML,"</ROOT>");
...
strXML:String;
//Грузим файл в strXML
var hFile : THandle;
nSize : Integer;
begin
hFile := FileOpen(FileXML,fmOpenRead);
try
nSize := FileSeek(hFile,0,2);
FileSeek(hFile,0,0);
SetLength(Result,nSize);
FileRead(hFile,Result[1],nSize);
finally
FileClose(hFile);
end;
end;
...
adoCommand.Open("exec MyStoredProc "+
{@I_UID} QuotedStr(UID) +","+
{@I_XML} QuotedStr(strXML)
);
--
set nocount on
declare @I_XML varchar(8000)--в SP будет text
--будет нечто подобное
set @I_XML = "
<?xml version="1.0" encoding="windows-1251"?>
<ROOT>
<DS A="1" B="&qqq" C="100" />
<DS A="2" B=""www" C="200" />
<DS A="3" B="<eee" C="300" />
</ROOT>
"
--
--внимание на &" и т.д.
--
declare @XMLID int
exec sp_xml_preparedocument @XMLID out, @I_XML
declare @tXML table(
A int,
B varchar(100),
C int
)
insert into @tXML select A,B,C
from openxml(@XMLID,"/ROOT/DS",1)with(
A int,
B varchar(100),
C int
)
exec sp_xml_removedocument @XMLID
select * from @tXML
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2004.04.04;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.042 c