Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 процедура возвращает несколько result sets  [new]
valv
Member

Откуда:
Сообщений: 122
процедура возвращает несколько result sets.

CREATE PROCEDURE sp1
AS
 select a, b from tb1
 select c, d from tb2
GO


ранее процедура вызвалась только с клиента, и не было проблем записать результаты.
сейчас возникла необходимость получить результаты работы этой процедуры из другой процедуры.
возможно ли уловить оба result sets с помощью t-sql?

изменить процедуру невозможно.
MS SQL 2012.
спасибо.
21 мар 13, 15:22    [14077771]     Ответить | Цитировать Сообщить модератору
 Re: процедура возвращает несколько result sets  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
Если рекорсеты совпадают то да
create  proc dbo.test
as
  select  * from sys.objects
  where object_id =3
  select* from sys.objects
    where object_id =5
GO

select *into  #test
from sys.objects
where object_id<>object_id
GO
insert into #test
exec   dbo.test
GO
select * from #test
GO
Drop table #test
GO 
drop proc dbo.test
21 мар 13, 15:29    [14077827]     Ответить | Цитировать Сообщить модератору
 Re: процедура возвращает несколько result sets  [new]
valv
Member

Откуда:
Сообщений: 122
Maxx,

спасибо.
Maxx
Если рекорсеты совпадают то да

извниняюсь, неудачно упростил код. в реальность 14 рекордсетов, часть первые 13 совпадают, последний это число. примерно так:
create  proc dbo.test
as
  select name, type from sys.objects
  where object_id =3
  select name, type from sys.objects
  where object_id =5
  select count(*)  as DailyTranCount from sys.objects
21 мар 13, 15:42    [14077937]     Ответить | Цитировать Сообщить модератору
 Re: процедура возвращает несколько result sets  [new]
Гость333
Member

Откуда:
Сообщений: 3683
valv,

Делаете CLR-обёртку над этой поцедурой, перед вызовом обёртки создаёте N временных таблиц, в обёртке получаете рекордсеты и раскидываете их по временным таблицам (при помощи SQLBulkCopy, например).

А почему, собственно, "изменить процедуру невозможно"?
21 мар 13, 15:50    [14078004]     Ответить | Цитировать Сообщить модератору
 Re: процедура возвращает несколько result sets  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
valv,

тада кина не будет :( скорее всего ,даже при людском создании таблицы и все такое количество полей должно быть одинаковым . НО у меня другой вопрос -как ВЫ собераетесь определить,что реально из первого рекорседа пришло,а что из 10го ?
21 мар 13, 15:52    [14078017]     Ответить | Цитировать Сообщить модератору
 Re: процедура возвращает несколько result sets  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
Гость333,

кста идея..100%
21 мар 13, 15:53    [14078019]     Ответить | Цитировать Сообщить модератору
 Re: процедура возвращает несколько result sets  [new]
invm
Member

Откуда: Москва
Сообщений: 9824
13821167
21 мар 13, 16:05    [14078129]     Ответить | Цитировать Сообщить модератору
 Re: процедура возвращает несколько result sets  [new]
valv
Member

Откуда:
Сообщений: 122
Гость333,
Гость333
Делаете CLR-обёртку
спасибо... собственно, это и начал делать, но оказалось чрезмерно сложно. на клиенте через ADO.NET всё элементарно.

автор
-как ВЫ собераетесь определить,что реально из первого рекорседа пришло,а что из 10го ?
не проблема, есть идентификаторы.

автор
А почему, собственно, "изменить процедуру невозможно"?
чужая процедура на чужом сервере.

как-то это нелогично: возвратить из обычной t-sql процедуры несколько рекордсетов можно, а записать c их уже никак.
ну что за язык такой странный? незамкнутый, что ли... или ещё недоделанный...
21 мар 13, 16:08    [14078162]     Ответить | Цитировать Сообщить модератору
 Re: процедура возвращает несколько result sets  [new]
Гость333
Member

Откуда:
Сообщений: 3683
invm
13821167

Парсить текстовый выхлоп sqlcmd средствами T-SQL — жуткая жуть, конечно :-)
21 мар 13, 16:24    [14078277]     Ответить | Цитировать Сообщить модератору
 Re: процедура возвращает несколько result sets  [new]
valv
Member

Откуда:
Сообщений: 122
invm,
спасибо за ссылку,

решил проблему через openrowset, он умеет возвращать рекордсет первый по порядку:
select * from openrowset('SQLNCLI', 'Server=;Trusted_connection=yes;', 'set NoCount on; set fmtonly off; exec srv.facts.proc 12;');


вопрос закрыт, всем спасибо
21 мар 13, 16:32    [14078329]     Ответить | Цитировать Сообщить модератору
 Re: процедура возвращает несколько result sets  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
valv
на клиенте через ADO.NET всё элементарно.


Вы пожинаете плоды написания серверного кода "специалистами по клиенту".
21 мар 13, 16:32    [14078330]     Ответить | Цитировать Сообщить модератору
 Re: процедура возвращает несколько result sets  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
valv
вопрос закрыт, всем спасибо


Передайте привет серверу! Ему очень понравится двойной вызов хп.
21 мар 13, 16:33    [14078338]     Ответить | Цитировать Сообщить модератору
 Re: процедура возвращает несколько result sets  [new]
Гость333
Member

Откуда:
Сообщений: 3683
valv
решил проблему через openrowset, он умеет возвращать рекордсет первый по порядку

Хм, а в стартовом сообщении вы про другое говорили:
автор
возможно ли уловить оба result sets с помощью t-sql?
21 мар 13, 16:37    [14078364]     Ответить | Цитировать Сообщить модератору
 Re: процедура возвращает несколько result sets  [new]
valv
Member

Откуда:
Сообщений: 122
pkarklin,
автор
Передайте привет серверу! Ему очень понравится двойной вызов хп.

запускаю процедуру 13 раз, записываю первую по порядку строку :).
затем через xp_cmdshell запускаю 14-тый раз, парсинг получить последнюю строку :)).
уже работает
чувствую себя аццким говнокодером и скриптоложцем :(
21 мар 13, 16:38    [14078368]     Ответить | Цитировать Сообщить модератору
 Re: процедура возвращает несколько result sets  [new]
qwerty112
Guest
valv
возможно ли уловить оба result sets с помощью t-sql?

как вариант, можно сделать через sp_AO.. и ADODB.Recordset
1
получить все result sets в ADODB.Recordset
2
через ADODB.Recordset.getstring - сериализовать в XML
(или через ADODB.Recordset.Save - сохранить в хмл-файл)
3
распарсить XML
(или загрузить из файла)
4
ADODB.Recordset.NextRecordset
21 мар 13, 16:47    [14078406]     Ответить | Цитировать Сообщить модератору
 Re: процедура возвращает несколько result sets  [new]
Гость333
Member

Откуда:
Сообщений: 3683
valv
запускаю процедуру 13 раз, записываю первую по порядку строку :)

1) По факту процедура вот с этим: "set fmtonly off" — запускается 26 раз;
2) Как 13 запусков помогают получить, например, пятый рекордсет?
21 мар 13, 16:48    [14078415]     Ответить | Цитировать Сообщить модератору
 Re: процедура возвращает несколько result sets  [new]
qwerty112
Guest
qwerty112
(или через ADODB.Recordset.Save - сохранить в хмл-файл)

даже, "симпатичнее" немного, - без файла

через ADODB.Recordset.Save - сохранить в ADODB.Stream в формате adPersistXML,
после чего - прочитать из ADODB.Stream "готовый" XML в переменную ... ну и дальше понятно
21 мар 13, 17:01    [14078495]     Ответить | Цитировать Сообщить модератору
 Re: процедура возвращает несколько result sets  [new]
valv
Member

Откуда:
Сообщений: 122
Гость333,

автор
1) По факту процедура вот с этим: "set fmtonly off" — запускается 26 раз;
да, верно. 2-2.5 секунды вся эта схема работает, хотя сама процедура 20 мс

автор
2) Как 13 запусков помогают получить, например, пятый рекордсет?
есть возможность получить "пятый рекордсет" первым, но это частный случай именно этой процедуры, в качестве общего решение не годится.

в будущем перепишу нормально, вариант что qwerty112 подсказал, а временно этот кривой путь.
21 мар 13, 17:47    [14078747]     Ответить | Цитировать Сообщить модератору
 Re: процедура возвращает несколько result sets  [new]
invm
Member

Откуда: Москва
Сообщений: 9824
Гость333
Парсить текстовый выхлоп sqlcmd средствами T-SQL — жуткая жуть, конечно :-)
Чего только не придумает разработчик ПО в приступе профессиональной изворотливости :)
21 мар 13, 18:14    [14078844]     Ответить | Цитировать Сообщить модератору
 Re: процедура возвращает несколько result sets  [new]
invm
Member

Откуда: Москва
Сообщений: 9824
Для жертв "multiple resultsets" и вложенных "insert exec":
+ Сделано на коленке, каждый может доработать по вкусу
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Xml;
using System.Text;
using System.IO;

public partial class UserDefinedFunctions
{
    private static void WriteDataTableToXml(DataTable dt, XmlWriter xw)
    {
        StringWriter sw = new StringWriter();
        dt.TableName = "row";
        dt.WriteXml(sw);

        XmlDataDocument xd = new XmlDataDocument();
        xd.LoadXml(sw.ToString());
        xd.DocumentElement.WriteContentTo(xw);
    }
    
    [SqlProcedure()]
    public static void ResultSetsToXML(SqlString AQuery, out SqlXml AResult)
    {
        MemoryStream s = new MemoryStream();

        XmlWriterSettings xws = new XmlWriterSettings();
        xws.ConformanceLevel = ConformanceLevel.Fragment;
        xws.Encoding = Encoding.Unicode;

        XmlReaderSettings xrs = new XmlReaderSettings();
        xrs.ConformanceLevel = ConformanceLevel.Fragment;

        using (XmlWriter xw = XmlWriter.Create(s, xws))
        {
            if (!AQuery.IsNull)
                using (SqlConnection cn = new SqlConnection("Context Connection=true"))
                {
                    cn.Open();
                    SqlCommand cmd = new SqlCommand(AQuery.Value, cn);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        do
                        {
                            xw.WriteStartElement("resultset");

                            DataTable dt = reader.GetSchemaTable();

                            xw.WriteStartElement("metadata");
                            WriteDataTableToXml(dt, xw);
                            xw.WriteEndElement();
                            
                            dt = new DataTable();
                            dt.Load(reader);

                            xw.WriteStartElement("data");
                            WriteDataTableToXml(dt, xw);
                            xw.WriteEndElement();
                            
                            xw.WriteEndElement();
                        }
                        while (!reader.IsClosed);
                    }
                }

            xw.Flush();
        }

        s.Position = 0;
        AResult = new SqlXml(XmlReader.Create(s, xrs));
    }
};
23 мар 13, 17:29    [14086351]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить