C# SQL Server:作为存储过程执行的结果返回select的结果
我有一个从C调用的存储过程:C# SQL Server:作为存储过程执行的结果返回select的结果,c#,sql-server-2008,stored-procedures,C#,Sql Server 2008,Stored Procedures,我有一个从C调用的存储过程: CREATE PROCEDURE [MySP] @ID int, @Exists bit OUTPUT AS BEGIN SET NOCOUNT ON; SET @Exists = 0 SELECT TOP 1 ID FROM MyTable WHERE ID = @ID IF @@ROWCOUNT = 0 BEGIN SELECT b.* FROM
CREATE PROCEDURE [MySP]
@ID int,
@Exists bit OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET @Exists = 0
SELECT TOP 1 ID
FROM MyTable
WHERE ID = @ID
IF @@ROWCOUNT = 0
BEGIN
SELECT b.*
FROM AnotherTable b
INNER JOIN AnotherTable2 c ON b.ID = c.ID
WHERE b.ID = @ID
END
ELSE
BEGIN
SET @Exists = 1
SELECT TOP 0 NULL
END
END
如果表MyTable中不存在@ID,则返回SELECT b.*,否则如果表中存在@ID,则不返回任何行
问题是,当@ID存在于表中时,存储过程会将两个表作为结果返回给C,一个来自SELECT TOP 1,另一个来自SELECT b.*并且我只想返回SELECT b.*那么我该怎么做呢?只需将所有逻辑替换为:
SELECT b.*
From AnotherTable b INNER JOIN
AnotherTable2 c
ON b.ID = c.ID
WHERE b.ID = @ID AND
NOT EXISTS (SELECT 1 FROM MyTable WHERE ID = @ID);
而且,如果您不想要复制品,您不妨:
SELECT b.*
From AnotherTable b
WHERE b.ID = @ID AND
EXISTS (SELECT 1 FROM AnotherTable2 c WHERE b.ID = c.ID) AND
NOT EXISTS (SELECT 1 FROM MyTable WHERE ID = @ID);
然后,了解表值函数。如果您想返回一个表,那么最好的方法(如果可行的话)是函数,而不是存储过程。
函数在其功能上受到更多限制,因此这并不总是可能的。存在以下用途:
CREATE PROCEDURE [MySP]
@ID int,
@Exists bit OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET @Exists = 0
IF EXISTS(SELECT TOP 1 ID FROM MyTable WHERE ID = @ID)
BEGIN
SELECT b.*
From AnotherTable b
INNER JOIN AnotherTable2 c on b.ID = c.ID
Where b.ID = @ID
END
ELSE
BEGIN
SET @Exists = 1
SELECT TOP 0 NULL
END
END
您得到的第二个结果是select top 0 null语句。这种方法的问题是必须执行整个select,我想要的是避免执行不必要的select,并在前面的select top 1。。。返回行。您所说的这种方法也可以通过使用MyTable的左连接和where子句中的filter by:where MyTable.column为NULL来实现。但这种方法不喜欢我,因为正如我所说的,您使sql server在处理和必要的选择时工作。@user1624552。在得出错误结论之前,您应该运行查询并查看SQL Server是如何优化它们的。这个解决方案很适合我。正如我对Gordon Linoff所说的,这个解决方案避免了sql server引擎通过首先检查是否存在来执行不必要的选择。你是不对的。第二个结果:仅当SELECT TOP 1返回行并且在我的案例中SELECT TOP 1不返回行时,才会执行SELECT TOP 0 NULL,因此第一个结果是从另一个表b中选择b*。。。而是执行。