这个SQL查询在哪里出错了?

时间:2017-05-10 00:04:37

标签: sql sql-server

我正在尝试执行以下操作:

  1. 检查表格是否不存在,如果是,请创建TABLE' tmpTriangleTransfer'。
  2. 检查表是否存在,如果存在,请删除TABLE' tmpTriangleTransfer'。
  3. 将从其他表中提取的数据插入第2个 - TABLE' tmpTriangleTransfer'。
  4. 的第5列
  5. 循环以及TABLE' tmpTriangleTransfer'中存在的每一行使用声明的信息更新第1列。
  6. 返回该表中的所有信息(格式化为报告)。
  7. 有人可以帮我弄清楚我做错了什么吗?我没有得到任何结果,即使我知道有记录(当我在最后一行只运行SELECT语句时,它显示记录,当我在中间运行SELECT DISTINCT语句时,它显示相同记录)。

    IF OBJECT_ID('tmpTriangleTransfer') IS NOT NULL
     DROP TABLE tmpTriangleTransfer;
    IF OBJECT_ID('tmpTriangleTransfer') IS NULL
    
    CREATE TABLE tmpTriangleTransfer
                (
                CompanyName varchar(max),
                OrderID decimal(19,2) NULL,
                DriverID int NULL,
                VehicleID int NULL,
                Phone varchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
                BOL varchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
                );
    
    INSERT INTO tmpTriangleTransfer (OrderID, BOL, DriverID, VehicleID, Phone)
    SELECT DISTINCT tblOrder.OrderID AS OrderID, tblOrder.BOL AS BOL, tblOrderDrivers.DriverID AS DriverID, tblDrivers.VehicleID AS VehicleID, tblWorker.Phone AS Phone
        FROM tblOrder WITH (NOLOCK)
            INNER JOIN tblActiveOrders
            ON tblOrder.OrderID = tblActiveOrders.OrderID
            INNER JOIN tblOrderDrivers
            ON tblOrder.OrderID = tblOrderDrivers.OrderID
            INNER JOIN tblDrivers
            ON tblOrderDrivers.DriverID = tblDrivers.DriverID
            INNER JOIN tblWorker
            ON tblDrivers.WorkerID = tblWorker.WorkerID
            WHERE tblOrder.CustID = 7317
            ORDER BY tblOrder.OrderID`
    
    
    DECLARE @MaxRownum INT
    SET @MaxRownum = (SELECT MAX(OrderID) FROM tmpTriangleTransfer)
    
    DECLARE @Iter INT
    SET @Iter = (SELECT MIN(OrderID) FROM tmpTriangleTransfer)
    
    WHILE @Iter <= @MaxRownum
    BEGIN
    
       UPDATE tmpTriangleTransfer
          SET tmpTriangleTransfer.CompanyName = 'Triangle'
       WHERE tmpTriangleTransfer.CompanyName IS NULL;
    
       SET @Iter = @Iter + 1
    
    END
    
    SELECT * from tmpTriangleTransfer WITH (NOLOCK)
    

2 个答案:

答案 0 :(得分:2)

您现有的查询过于复杂。事实上,您不需要临时表,WHILE循环或任何其他内容 - 只需一个SELECT即可:

SELECT
    'Triangle' AS CompanyName,
    tblOrder.OrderId,
    tblOrder.BOL,
    tblOrderOrders.DriverID,
    tblDrivers.VehicleID,
    tblWorker.Phone
FROM
    tblOrder
    OUTER JOIN tblActiveOrders ON tblOrder.OrderID = tblActiveOrders.OrderID
    OUTER JOIN tblOrderDrivers ON tblOrder.OrderID = tblOrderDrivers.OrderID
    OUTER JOIN tblDrivers      ON tblOrderDrivers.DriverID = tblDrivers.DriverID
    OUTER JOIN tblWorker       ON tblDrivers.WorkerID = tblWorker.WorkerID
WHERE
    tblOrder.CustID = 7317
ORDER BY
    tblOrder.OrderID
  • 我已将您的查询更改为使用OUTER JOIN而不是INNER JOIN,因为我怀疑这是没有数据返回的主要原因。 INNER JOIN要求两个表(关系)中都存在行,并且我怀疑您Orders没有Drivers,或者Order不是ActiveOrders。如果您知道相关行始终存在,请将联接更改为INNER JOIN
  • 您可以直接在查询中返回文字,就像我在SELECT 'Triangle' AS CompanyName部分中所做的那样,而您似乎是手动将其添加到输出临时表中。
  • 您的代码似乎没有做任何需要WITH (NOLOCK)修饰符的事情 - 它在任何地方重复的事实使它看起来像Cargo-Cult Programming
  • 提示:在SQL中,写成的SELECT语句不代表其逻辑执行顺序。它应该按以下顺序阅读:FROM > WHERE > [GROUP BY >] SELECT > ORDER BY
    • 这就是为什么在.NET Linq中.Select()调用通常在最后,而不是开头,因为之前的Linq表达式定义了数据源。
  • 此查询可以通过将其转换为接受CustID作为参数的表定义函数进行参数化,我还假设您拥有公司名称&#34; Triangle&#34;存储在某个地方的表格中 - 将其作为单个查询的字面值嵌入是一种代码味道 - 7317 /&#34; Triangle&#34 ;?
    • 相关说明:一般来说,查询仅包含SELECT个数据(并且不执行任何INSERT / UPDATE / DELETE / ALTER / CREATE语句)应该是表值UDF或视图而不是存储过程 - 这样它们就可以从存储过程无法获得的函数组合,查询组合和运行时执行计划优化中受益。
  • 如果您能够,请查看是否可以从表名中删除tbl前缀(使用&#34; tbl&#34;因为前缀有其防御者,但我个人的观点是,它是一个过时的开发人员辅助工具,因为今天的数据库工具显示了类型信息,它使数据库重构变得更加困难(例如将表转换为视图)。

答案 1 :(得分:0)

结合戴的建议和雇主的要求:

`SELECT 'Triangle' AS CompanyName, tblOrder.OrderId AS OrderID, tblOrder.BOL AS BOL, tblOrderDrivers.DriverID AS DriverID, tblDrivers.VehicleID AS VehicleID, tblWorker.Phone AS Phone
FROM tblOrder WITH (NOLOCK)
        INNER JOIN tblActiveOrders WITH (NOLOCK)
        ON tblOrder.OrderID = tblActiveOrders.OrderID
    INNER JOIN tblOrderDrivers WITH (NOLOCK)
        ON tblOrder.OrderID = tblOrderDrivers.OrderID
    INNER JOIN tblDrivers WITH (NOLOCK)
        ON tblOrderDrivers.DriverID = tblDrivers.DriverID
    INNER JOIN tblWorker WITH (NOLOCK)
        ON tblDrivers.WorkerID = tblWorker.WorkerID
WHERE
    tblOrder.CustID = 7317
ORDER BY
    tblOrder.OrderID desc`