如何检查表的 ID 是否与 SQL 中另一个表的另一个 ID 匹配

时间:2021-07-21 22:31:33

标签: sql sql-server tsql

所以我有 4 个参数,其中一个作为存储过程的输入参数给出(它就像一个代表唯一操作的代码),我需要将这些 ID 与另一个表中的另一个 ID 匹配,所以我需要在表2中检查ID的“DeliverTypeID”、“ScheduleTypeID”、“CourseID”,如果它们都与表1相同,如果确实如此,则应该打印出相应的记录。

我需要通过存储过程进行此选择。

这是我目前的代码:

USE [Database]
GO
/****** Object:  StoredProcedure [dbo].[nameSP]  ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
ALTER PROCEDURE [dbo].[nameSP]  
    @ScheduleID int
AS
BEGIN   
    SET NOCOUNT ON;

    DECLARE @DeliverTypeID int
    DECLARE @ScheduleTypeID int
    DECLARE @CourseID int

    SELECT @DeliverTypeID = DeliverTypeid
        , @ScheduleTypeID = [Cod Tipo Acção]
        , @CourseID = [Cod Curso]
    FROM table1
    INNER JOIN table2 on table1.[CourseID] = table2.CourseID
    INNER JOIN table2 on table1.[ScheduleTypeID] = table2.ScheduleTypeID
    INNER JOIN table2 on table1.[DeliverTypeID] = table2.DeliverTypeID
    WHERE table1.[Cod Acção] = @ScheduleID
    AND (CourseID = @CourseID OR table2.CourseID is null)
    AND (ScheduleTypeID = @ScheduleTypeID)
    AND (DeliverTypeID = @DeliverTypeID)
END

最小示例:

Table1

ScheduleID|CourseID|DeliverTypeID|ScheduleTypeID|
67212     |2000    |1            |1             |
69212     |3000    |2            |2             |
69124     |4000    |3            |3             |
70124     |5000    |4            |4             |

Table2
|CourseID|DeliverTypeID|ScheduleTypeID|
|3000    |1            |1             |
|2000    |2            |3             |
|5000    |3            |2             |
|NULL    |2            |1             |

非常感谢您。

4 个答案:

答案 0 :(得分:0)

将步骤分开。先赋值,再检查记录。

for (Bar bar = (null != foo) ? foo.getBar() : null; bar != null;) {
    System.out.println("Success: " + bar);
    break;
}

如果您正在运行支持它的 SQL Server 版本(您没有提及您正在使用的版本),那么您可以在第二个查询之前运行 DECLARE @DeliverTypeID int DECLARE @ScheduleTypeID int DECLARE @CourseID int SELECT @DeliverTypeID = DeliverTypeid , @ScheduleTypeID = [Cod Tipo Acção] , @CourseID = [Cod Curso] FROM table1 WHERE table1.[Cod Acção] = @ScheduleID SELECT CourseID, ScheduleTypeID, DeliverTypeID -- and other columns you want from table 2 FROM table2 WHERE (CourseID = @DeliverTypeID) AND (ScheduleTypeID = @ScheduleTypeID) AND (DeliverTypeID = @CourseID OR table2.CourseID is null) 以处理任何记录。

答案 1 :(得分:0)

我认为您正在寻找的是以下内容。我认为您不需要变量,只需要单个连接中的正确逻辑(您似乎不太可能想要 3 次连接 Table2)。

ALTER PROCEDURE [dbo].[nameSP]
(
    @ScheduleID int
)
AS
BEGIN   
    SET NOCOUNT, XACT_ABORT ON;

    -- Select specific columns you wish to return rather than *
    SELECT t2.*
    FROM table1 t1
    INNER JOIN table2 t2 ON (t2.CourseID = t1.[CourseID] OR t2.CourseID IS NULL)
        AND t2.[ScheduleTypeID] = t1.ScheduleTypeID
        AND t2.[DeliveryTypeID] = t1.DeliveryTypeID
    WHERE t1.ScheduleID = @ScheduleID;

    -- Tell the calling context that the SP executed OK (0 means OK any other number means error).
    RETURN 0;
END;

请注意,为了清楚起见,我建议使用表别名。

答案 2 :(得分:-1)

这是您程序的正确形式

ALTER PROCEDURE [dbo].[nameSP]  
    @ScheduleID int
AS
BEGIN   
    SET NOCOUNT ON;

    SELECT *       
    FROM table1
    INNER JOIN table2 on table1.[CourseID] = table2.CourseID 
    AND table1.[ScheduleTypeID] = table2.ScheduleTypeID
    AND table1.[DeliverTypeID] = table2.DeliverTypeID
    WHERE table1.[Cod Acção] = @ScheduleID AND table2.CourseID is null
RETURN
END

使用以下命令运行

exec nameSP 5

答案 3 :(得分:-1)

所以还有一个问题是你,而且似乎没有其他人甚至在考虑处理它,它比你想象的要大,不明显,可能会完全弄乱你的服务器,让你很快被砍掉。

 @ScheduleID int

我知道正确的一行,这么大的问题的信息太少了。

Parameter Sniffing. - (是的,将近一个小时,我会分解)

您可能没有听说过这个,但它可能会破坏访问您的存储过程正在访问的任何表的每个进程。

什么是参数嗅探...

想象一下园丁(服务器核心)上层管理人员(你)制定了一个“挖杂草”的程序......

中层管理人员(服务器引擎)查看第一个花园,它有 10 平方英尺和两棵杂草,因此他们根据此结果编译任务,给 1 个园丁 Joe 工具棚钥匙并告诉他们拿起镘刀,开始工作,他们就像一只小旅鼠,决心在不知道超时的情况下完成任务,只有两株杂草,因此您已针对此结果进行了优化...

中层管理人员 - 根据挖杂草的参数将此计划存储在他们的园艺计划缓存中...

如果你问中层经理你用什么程序来“挖杂草”,他们会说“铲子和园丁”... 指向乔

<块引用>

乔:“你好”

工作 2 来了,这是一个 278 英亩的高尔夫球场,他们看着这个新任务,给园丁工具棚的钥匙,告诉他拿他的镘刀,他尽可能快地跳到它身上没有超时的概念并开始挖掘杂草......

另一个园丁想开始工作,但这个永远堵在路上的小家伙有棚子的钥匙,高尔夫球手想打球,但他在果岭上,当他拔草时你不能打球,看门人鲍勃想在棚子里添加新工具,但我们进不去,因为那边挖杂草的乔正在忙着挖杂草。

所以现在你正在阻止其他园丁、高尔夫球手和采购人员做他们的事情,直到你完成,而现在采购正在等待园丁和其他人的一小群人的钥匙,另一个采购任务开始了,现在他们被困在队列中,等待这个人完成对棚钥匙的等待,因为他有购买分类帐。

然后会计被困在他们身后,不知不觉整个公司(系统)都停了下来,因为乔有一把该死的工具棚钥匙,现在每个人都在加班等待他挖高尔夫球场用抹子...

但这不是乔斯的错,他努力工作,你不能因为他被告知去做而解雇他。

它可能比阻塞更糟糕,您可能会在存储过程中死锁,并且您可能会损坏表。

如果您认为我们可以回滚...回滚是单线程的!!!所以乔会跑来跑去重新种植他刚挖出来的所有杂草!!!

因此,每当您设计存储过程时,总是在使用参数的任何地方添加 With Recompile,并且看到这是一个存储过程,应该始终如此!

这样想一下,中层管理人员每次都会重新评估任务,然后去哦,这是一项艰巨的工作,最好让整个团队在割草机上并行......而且没有人得到划桨。

那么至少当下一个 10 英尺的小花园出现时......你还没有 500 名园丁骑着割草机摇摆不定。

ALTER PROCEDURE [dbo].[nameSP]  
    @ScheduleID int
    WITH RECOMPILE
AS
BEGIN   
    SET NOCOUNT ON;

    SELECT CourseID, ScheduleTypeID, DeliverTypeID, Cod Acção    
    FROM table1
    INNER JOIN table2 on table1.[CourseID] = table2.CourseID 
    AND table1.[ScheduleTypeID] = table2.ScheduleTypeID
    AND table1.[DeliverTypeID] = table2.DeliverTypeID
    WHERE table1.[Cod Acção] = @ScheduleID AND table2.CourseID is null 

RETURN
END