Легко в MySQL:
Пользователи UPDATE AS U1, пользователи AS U2 SET U1.name_one = U2.name_colX WHERE U2.user_id = U1.user_id
Кажется, что нет простого простого способа сделать это без взлома или серьезного сдвига парадигмы. Похоже, что лучший способ состоит в том, чтобы просто отделить исходные procs и завершить еще один процесс, чем раньше:
Старый способ:
create procedure dbo.GetSomething
as
begin
select * from dbo.Person;
select * from dbo.Car;
end;
Новый способ:
create procedure dbo.GetPeople
as
begin
select * from dbo.Person;
end;
create procedure dbo.GetCars
as
begin
select * from dbo.Car;
end;
-- This gives the same result as before
create procedure dbo.GetSomething
as
begin
exec dbo.GetPeople;
exec dbo.GetCars;
end;
Тогда, когда я нахожусь в другом proc и нуждаюсь в обоих наборах результатов, мне просто нужно будет называть их по одному.
Вы можете поместить несколько результирующих наборов в виде xml в таблицу
. Таким образом, когда вы хотите получить доступ ко всем этим результатам, вы проанализируете столбец с результатом в табличной форме
На землях TSQL вы застряли.
Вот трюк (некоторые могут вызвать полу-хаки), который я использовал один раз.
/* START TSQL CODE */
/* Stored Procedure Definition */
Use Northwind
GO
IF EXISTS
(
SELECT * FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_TYPE = N'PROCEDURE' and ROUTINE_SCHEMA = N'dbo' and ROUTINE_NAME = N'uspOrderDetailsByCustomerId'
)
BEGIN
DROP PROCEDURE [dbo].[uspOrderDetailsByCustomerId]
END
GO
CREATE Procedure dbo.uspOrderDetailsByCustomerId
(
@CustomerID nchar(5)
, @ResultSetIndicator smallint = 0
)
AS
BEGIN
SET NOCOUNT ON
/* ResultSet #1 */
if (@ResultSetIndicator = 0 OR @ResultSetIndicator = 1)
BEGIN
SELECT
c.CustomerID, c.CompanyName /*,c.ContactName,c.ContactTitle,c.[Address],c.City,c.Region,c.PostalCode,c.Country ,c.Phone,c.Fax */
FROM
Customers c
JOIN Orders o ON c.CustomerID = o.CustomerID
WHERE
c.CustomerID = @CustomerID
END
/* */
/* ResultSet #2 */
if (@ResultSetIndicator = 0 OR @ResultSetIndicator = 2)
BEGIN
SELECT o.OrderID,o.CustomerID /* ,o.EmployeeID,o.OrderDate,o.RequiredDate,o.ShippedDate,o.ShipVia ,o.Freight,o.ShipName,o.ShipAddress,o.OrderID,o.CustomerID,o.EmployeeID,o.OrderDate */
FROM
Orders o
WHERE
o.CustomerID = @CustomerID
ORDER BY
o.CustomerID , o.OrderID
END
/* */
/* ResultSet #3 */
if (@ResultSetIndicator = 0 OR @ResultSetIndicator = 3)
BEGIN
SELECT od.OrderID,od.ProductID /* ,od.UnitPrice,od.Quantity,od.Discount */
FROM
[Order Details] od
WHERE
exists (select null from dbo.Orders innerOrds where innerOrds.OrderID = od.OrderID and innerOrds.CustomerID = @CustomerID )
ORDER BY
od.OrderID
END
SET NOCOUNT OFF
END
GO
/* Get everything */
exec dbo.uspOrderDetailsByCustomerId 'ALFKI'
IF OBJECT_ID('tempdb..#TempCustomer') IS NOT NULL
begin
drop table #TempCustomer
end
CREATE TABLE #TempCustomer
(
[CustomerID] nchar(5)
, [CompanyName] nvarchar(40)
)
INSERT INTO #TempCustomer ( [CustomerID] , [CompanyName])
exec dbo.uspOrderDetailsByCustomerId 'ALFKI' , 1
Select * from #TempCustomer
IF OBJECT_ID('tempdb..#TempOrders') IS NOT NULL
begin
drop table #TempOrders
end
CREATE TABLE #TempOrders
(
OrderID int
, [CustomerID] nchar(5)
)
INSERT INTO #TempOrders ( OrderID , [CustomerID] )
exec dbo.uspOrderDetailsByCustomerId 'ALFKI' , 2
Select * from #TempOrders
IF OBJECT_ID('tempdb..#TempOrderDetails') IS NOT NULL
begin
drop table #TempOrderDetails
end
CREATE TABLE #TempOrderDetails
(
OrderID int
, [ProductID] int
)
INSERT INTO #TempOrderDetails ( OrderID , [ProductID] )
exec dbo.uspOrderDetailsByCustomerId 'ALFKI' , 3
Select * from #TempOrderDetails
IF OBJECT_ID('tempdb..#TempOrderDetails') IS NOT NULL
begin
drop table #TempOrders
end
IF OBJECT_ID('tempdb..#TempOrders') IS NOT NULL
begin
drop table #TempOrders
end
IF OBJECT_ID('tempdb..#TempCustomer') IS NOT NULL
begin
drop table #TempCustomer
end
Создайте SqlDataAdapter, установите его SelectCommand для выполнения SP «GetSomething», а затем используйте адаптер данных для заполнения DataSet. DataSet будет содержать столько же данных DataTable, сколько у вас есть «select», которые возвращают набор записей из SP.
Вот как выглядит ваш код:
System.Data.SqlClient.SqlDataAdapter da = new System.Data.SqlClient.SqlDataAdapter();
System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
cmd.Connection = myConnectionObject;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "GetSomething";
da.SelectCommand = cmd;
System.Data.DataSet ds = new DataSet();
da.Fill(ds);
// at this point, the (ds) object contains DataTables created from the recordsets returned by the SP
DataTable dt0 = ds.Tables[0];
DataTable dt1 = ds.Tables[1];
// note that dt0 corresponds to the FIRST recordset returned by the SP, etc.
String myConnString = "User ID="username";password="password";Initial Catalog=pubs;Data Source=Server";
SqlConnection myConnection = new SqlConnection(myConnString);
SqlCommand myCommand = new SqlCommand();
SqlDataReader myReader ;
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Connection = myConnection;
myCommand.CommandText = "MyProc";
try
{
myConnection.Open();
myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
//Write logic to process data for the first result.
}
myReader.NextResult();
while (myReader.Read())
{
//Write logic to process data for the second result.
}
}
Хотя это, похоже, не поддерживается в T-SQL изначально, если вы используете хранимую процедуру CLR для вас, то вы должны иметь возможность создать хранимую процедуру на предпочитаемом языке .Net, который использует функцию SqlDataReader.NextResult()
, чтобы перейти к желаемому набору результатов, а затем отправить SqlDataReader обратно через метод SqlPipe.Send(SqlDataReader)
. Вам просто нужно пройти в SQL для выполнения и желаемый результат, заданный в качестве параметров для этого proc.
Это позволит вам работать с proc как есть, не изменяя его, чтобы отправлять обратно все или только один результирующий набор.
Der. Прочтите весь вопрос, прежде чем писать ответ! :-P
Если вы пытаетесь работать с результатами на земле TSQL, вам нужно будет каким-то образом сохранить результаты отдельно. Написание результатов для таблиц Temp - это, пожалуй, лучший выбор, поскольку вам не нужно будет зависеть от выравнивания столбцов (или нет, в зависимости от ситуации) и может обрабатывать данные «естественным» способом для SQL Server. Например,
create proc test_something
as begin
select a, b into temp1 from table1
select b, c into temp2 from table2
end
go
exec dbo.test_something()
select * from temp1
select * from temp2