v8: Подскажите по ADO и хранимым процедурам SQL #553806


#0 by Smallrat
Хочу выполнить хранимую процедуру и получить вовращаемое ей значение:
#1 by Axel2009
действуй
#2 by Rie
А в чём проблема-то? Всё тот же Execute...
#3 by Smallrat
мля - случайно нажал отправить. --- Хочу имитировать вызов процедуры которую выловил профайлером: такой вот текст: begin  set nocount on end будучи запущенным как скрипт оно возвращет числовое значение в res
#4 by philll
#5 by Smallrat
Я написал всё в 1С и всё выполняется, только возвращает какую-то пургу:
#6 by philll
какую пургу?
#7 by Rie
Полностью результат
#8 by Rie
+ А ему только количество надо.
#9 by Rie
Если получил RecordSet - то RecordCount возьми. Не оно?
#10 by Smallrat
там еще параметры выставлялись так вот - оно выываливается с ошибкой на MoveFirst Произошла исключительная ситуация (ADODB.Recordset): Операция не допускается, если объект закрыт. Несколько часов пропарился, понял что там возврааются наборы, и типа надо делать NextRecordset Только RS1 = RS.NextRecordset; сразу же мне дает Неопределено и ничего из этих наборов вытащить не удается
#11 by philll
Это не то?
#12 by Rie
Так выставь параметры. Прямо в тексте запроса.
#13 by Smallrat
RecordCount  - ошибка чтения значения. прочитал там товарищ сказал что может не получится ( Eof не отрабатывает на закрытом наборе с параметрами проблем нет - я все выставил через Command.Parameters.Append(Command.CreateParameter("@Cli",            2,    1, 9, 1));
#14 by Smallrat
так нету меня никакого запроса - есть только выполнение команды с типом  "adcmdstoredproc"
#15 by Rie
А зачем ты выбираешь adCmdStoredProc? Вызвать и без этого можно. То же самое, что в - запихни в CommandText.
#16 by Smallrat
чессно говоря не знаю, я с ADO первый раз работаю. Просто с примера вызова хранимой процедуры слизал. Думал - так правильней. До меня только сейчас дошло: select res = @r  - оно что, возвращает просто количество записей в @r ?
#17 by Smallrat
там есть параметры типа DateTime (аля  @DateIn = {ts' 2011-06-06 15:21:09' } ), как их передать в текст запроса ?
#18 by Smallrat
+ а блин - это ж просто текст, туплю
#19 by Rie
Непонятно, что оно возвращает. Оно возвращает результат выполнения PayBill. Количество записей - это гипотеза. (Причём, боюсь, неверная - не глянул, что там set nocount on выставляется).
#20 by DmitrO
не не совсем дошло еще.. количество записей в типе int? :)
#21 by Smallrat
да, точно )) тогда я не понимаю - раз хранимая процедура возвращает int, то почему в 1С оно возвращает закрытый COM объект ?
#22 by DmitrO
скажи лучше для начала почему у тебя в примере в процедура называется PayBill, а в называется SP_PayBill?
#23 by Smallrat
а - перередактировал )), она выполняется и делает всё что надо. ТОлько не могу отловить возвращаемое значение - а там, я так понял, коды ошибок выполнения.
#24 by DmitrO
Потому что так написана процедура.
#25 by DmitrO
тебе именно эти коды ошибок и нужно получить?
#26 by Smallrat
по идее да. я уже правда придумал как без этого обойтись, но мне все равно интересно, я посмотрел текст процедуры там возвращается int. я плохо знаю ADO и SQL. но может select res = @r как раз преобразует @r в recordset, который можно считать. а просто число Execute не может вернуть, потому что возвращает рекордсеты ?
#27 by Smallrat
Если не удастся мне обойтись без кодов ошибок - буду делать commandtext, как сказал У меня вот еще вопрос: Почему надо соблюдать очередность присвоения параметров процедуры ? Command.Parameters.Append(Command.CreateParameter("@Par2",            2,1,,2)); дает выполнение с параметрами 1,2, а если  поменять местами строчки то даёт 2,1 Зачем тогда имена ?
#28 by DmitrO
вобщем выполнить процедуру есть два способа: 1. текстом запроса (adCmdText) текст команды должен быть такой: declare @r int exec @r = SP_PayBill ... --параметры процедуры select @r --для получения статуса возврата процедуры (return_status) при этом статус возврата будет в рекордсете состоящем из одного поля и одной записи, но похоже во втором рекордсете, т.к. похоже процедура сама выдает один рекордсет (возможно ошибочно). 2. вызовом по RPC (adCmdStoredProc) текст команды должен быть такой: SP_PayBill Чтобы получить статус возврата надо обязательно добавлять параметр (вроде первый он должен быть) с типом направления adParamReturnValue и после выполнения читать его значение.
#29 by DmitrO
+ во втором случае надо обязательно соблюдать порядок параметров как в объявлении процедуры, имена параметров игнорируются.
#30 by DmitrO
собственно у MSSQL имена параметров всегда игнорируются.
#31 by DmitrO
++ да, еще замечание Значения возвращаемых параметров (adParamOutput, adParamReturnValue) будут доступны только после получения всех результатов команды (после выполнения всех необходимых RS = RS.NextRecordset;).
#32 by Smallrat
RS = RS.NextRecordset у меня сразу неопределено возвращает ( Но по второму варианту (через adParamReturnValue ) у меня получилось получить это возвращаемое значение !!! такое же как и через запрос в SQL management studio. почему то без NextRecordset... просто в Command.Parameters.Value, ну да ладно... Большое спасибо за помощь!!, а то я вчера полдня убил чтобы дотрясти эту штуку, просто из принципа ))
#33 by DmitrO
>>почему то без NextRecordset... просто в Command.Parameters.Value, ну да ладно... потому что процедура возвращает всего один рекордcет, и он пустой (не содержит записей), поэтому буфер TDS протокола (по которому работает MSSQL) уже можно протолкнуть до возвращаемых параметров и oledb провайдер это делает. По правде говоря, параметры передаются когда последний рекордсет стоит на последней записи.
#34 by DmitrO
Главное четко понимать, что данные результатов передаются последовательно.
#35 by Smallrat
кажется я понял %( А что - так будет всегда когда возвращаемый результат не рекордсет, число там или строка ?
#36 by Smallrat
* то есть когда возвращаемое значение не рекордсет, а число или строка.
#37 by DmitrO
возвращаемые результаты с MSSQL можно разделить на три типа: 1. рекордсет Обычно формируется в результате выполнения предложения запроса SELECT (ряд других обычно спец. предложений запроса могут формировать результат такого же типа) Представляет из себя последовательно перебираемый набор записей с одинаковым набором полей. формируется в результате выполнения DML предложения запроса (INSERT, UPDATE, DELETE) В ADO читается из свойства Recordset::RecordCount. Представляет из себя значение типа int - количество обработанных записей. 3. значения возвращаемых параметров процедуры (возможно только при RPC вызове) Первые два всегда выдаются сервером последовательно, по ходу  выполнения. Причем не важно внутри процедуры или внутри процедуры вызванной из процедуры и т.п. или просто в пакете команд идет выполнение, результаты формируются последовательно по ходу выполнения. А значения возвращаемых параметров процедуры всегда идут вконце. Во время передачи результата типа рекордсет не известно сколько записей всего в текущем наборе. В общем случае этого не знает даже сервер он просто читает и отправляет записи, поэтому в ADO Recordset::RecordCount равно -1. Все выше сказанное относится не столько к ADO сколько к протоколу TDS и клиентам его отрабатывающим: - ODBC драйвер {SQL Server} - OLEDB провайдер {SQLOLEDB} - поставщик данных ADO.NET для MSSQL, пространство имен  System.Data.SqlClient
#38 by Smallrat
Спасиб )) буду переваривать.
Тэги:
Ответить:
Комментарии доступны только авторизированным пользователям

В этой группе 1С