2014-10-20 35 views
0

此查詢返回正確的結果。SQL Server:使用TOP或查詢時查詢失敗

SELECT 
    a.Company, a.FiscalYear, a.FiscalPeriod, 
    a.JournalCode, a.JournalNum, a.JournalLine, a.Description, 
    a.JEDate, a.GroupID, a.PostedBy, a.PostedDate, 
    a.SourceModule, 
    b_1.PartDescription, b_1.PartNum, b_1.PONum, 
    b_1.POLine, b_1.VendorID, b_1.VendorNum, b_1.VendorName 
FROM 
    epicor905.dbo.GLJrnDtl AS a 
LEFT OUTER JOIN 
    (SELECT 
     a.Company, a.TranNum, a.TranDate, a.PartNum, a.WareHouseCode, a.TranQty, 
     a.MtlUnitCost, a.ExtCost, a.PONum, a.POLine, a.PORelNum, a.PartDescription, 
     a.VendorNum, c.VendorID, c.Name AS VendorName, a.POUnitCost, a.POReceiptQty, 
     a.GLTrans, a.PostedToGL, b.JournalNum, b.JournalLine, b.JournalCode, 
     b.FiscalYear 
    FROM 
     epicor905.dbo.PartTran AS a 
    INNER JOIN 
     epicor905.dbo.TranGLC AS b ON a.Company = b.Company 
            AND a.SysDate_ = b.Key1 
            AND a.SysTime = b.Key2 
            AND a.TranNum = b.Key3 
    LEFT OUTER JOIN 
     epicor905.dbo.Vendor AS c ON a.Company = c.Company 
           AND a.VendorNum = c.VendorNum 
    WHERE 
     (b.RelatedToFile = 'PartTran') 
     AND (a.PostedToGL = 1)) AS b_1 ON a.Company = b_1.Company 
             AND a.JournalCode = b_1.JournalCode 
             AND a.FiscalYear = b_1.FiscalYear 
             AND a.JournalNum = b_1.JournalNum 
             AND a.JournalLine = b_1.JournalLine 
WHERE 
    (a.FiscalYear = 2014) 

以下查詢不起作用。

他們都失敗,並從字符串轉換日期和/或時間時

轉換失敗。

我試過在JOIN條款中使用ISDATE(col) == 1,但它似乎沒有幫助。

新增TOP(10)

SELECT TOP(10) a.Company,a.FiscalYear,a.FiscalPeriod,a.JournalCode,a.JournalNum,a.JournalLine,a.Description, 
       a.JEDate,a.GroupID,a.PostedBy,a.PostedDate,a.SourceModule,b_1.PartDescription,b_1.PartNum,b_1.PONum, 
       b_1.POLine,b_1.VendorID,b_1.VendorNum,b_1.VendorName 
FROM epicor905.dbo.GLJrnDtl AS a 
     LEFT OUTER JOIN (SELECT a.Company,a.TranNum,a.TranDate,a.PartNum,a.WareHouseCode,a.TranQty,a.MtlUnitCost,a.ExtCost, 
           a.PONum,a.POLine,a.PORelNum,a.PartDescription,a.VendorNum,c.VendorID,c.Name AS VendorName, 
           a.POUnitCost,a.POReceiptQty,a.GLTrans,a.PostedToGL,b.JournalNum,b.JournalLine,b.JournalCode,b.FiscalYear 
         FROM epicor905.dbo.PartTran AS a 
           INNER JOIN epicor905.dbo.TranGLC AS b 
             ON a.Company = b.Company 
              AND a.SysDate_ = b.Key1 
              AND a.SysTime = b.Key2 
              AND a.TranNum = b.Key3 
           LEFT OUTER JOIN epicor905.dbo.Vendor AS c 
              ON a.Company = c.Company 
               AND a.VendorNum = c.VendorNum 
         WHERE (b.RelatedToFile = 'PartTran') 
           AND (a.PostedToGL = 1)) AS b_1 
        ON a.Company = b_1.Company 
         AND a.JournalCode = b_1.JournalCode 
         AND a.FiscalYear = b_1.FiscalYear 
         AND a.JournalNum = b_1.JournalNum 
         AND a.JournalLine = b_1.JournalLine 
WHERE (a.FiscalYear = 2014) 

添加順序按

SELECT a.Company,a.FiscalYear,a.FiscalPeriod,a.JournalCode,a.JournalNum,a.JournalLine,a.Description, 
     a.JEDate,a.GroupID,a.PostedBy,a.PostedDate,a.SourceModule,b_1.PartDescription,b_1.PartNum,b_1.PONum, 
     b_1.POLine,b_1.VendorID,b_1.VendorNum,b_1.VendorName 
FROM epicor905.dbo.GLJrnDtl AS a 
     LEFT OUTER JOIN (SELECT a.Company,a.TranNum,a.TranDate,a.PartNum,a.WareHouseCode,a.TranQty,a.MtlUnitCost,a.ExtCost, 
           a.PONum,a.POLine,a.PORelNum,a.PartDescription,a.VendorNum,c.VendorID,c.Name AS VendorName,a.POUnitCost, 
           a.POReceiptQty,a.GLTrans,a.PostedToGL,b.JournalNum,b.JournalLine,b.JournalCode,b.FiscalYear 
         FROM epicor905.dbo.PartTran AS a 
           INNER JOIN epicor905.dbo.TranGLC AS b 
             ON a.Company = b.Company 
              AND a.SysDate_ = b.Key1 
              AND a.SysTime = b.Key2 
              AND a.TranNum = b.Key3 
           LEFT OUTER JOIN epicor905.dbo.Vendor AS c 
              ON a.Company = c.Company 
               AND a.VendorNum = c.VendorNum 
         WHERE (b.RelatedToFile = 'PartTran') 
           AND (a.PostedToGL = 1)) AS b_1 
        ON a.Company = b_1.Company 
         AND a.JournalCode = b_1.JournalCode 
         AND a.FiscalYear = b_1.FiscalYear 
         AND a.JournalNum = b_1.JournalNum 
         AND a.JournalLine = b_1.JournalLine 
WHERE (a.FiscalYear = 2014) 
ORDER BY a.JournalNum 

而且,這裏是這個距離的Epicor的一些信息。

Summary:  XA How to determine Key fields in TranGLC table? 
Book:   Support Solutions 
Page:   10175MPS 

PAGE: 10175MPS Updated: 11/21/2012 

PROBLEM: 
XA How to determine Key fields in TranGLC table? The fields will be different depending on the TranGLC.RelatedToFile. 

RESOLUTION: 
In order to determine this, you need to find the Primary Index for the RelatedToFile's table. 

1. Open Data Dictionary Viewer 
2. Tools > Personalization 
3. Click in the Indexes grid and select the pulldown on the "Collections" and uncheck the "Hidden" checkbox for PrimaryIndex 
4. Select the RelatedToFile table in the Data Dictionary 
5. View the Primary Index for that table 
**The Key fields will be listed in order separated by a comma. The Company field is not included as the first Key field in the TranGLC table, so that field can be ignored.** 

Example: 
TranGLC.RelatedToFile = PartTran 
The Primary Index for PartTran = sysdttime 
*Note the Index fields for the primary index (Company,SysDate,SysTime,TranNum)* 
**Company will not be one of the Key fields** 
Key1 = SysDate 
Key2 = SysTime 
Key3 = TranNum 

VERSION: 
9.04.503 
+0

'a.SysDate_ = b.Key1 a.SysTime = b.Key2'這些字段的數據類型是什麼?我猜他們是不一樣的。 – smr5 2014-10-20 20:55:44

+0

@Sam可惜他們不是,我也沒有任何控制權。 – MattAitchison 2014-10-20 20:57:43

+0

這是你的問題。對話錯誤正在發生,因爲那不是因爲'order by或top..'什麼是'b.Key1'的數據類型? – smr5 2014-10-20 21:00:44

回答

2

查詢的失敗無關與任何TOPORDER BY。問題是,在這個查詢的某處,你是比較或接合DATETIME類型的一列和另一(N)VARCHAR類型的,而後者列包含某處的值不能轉化爲DATETIME。通過添加TOPORDER BY,優化器只是構造一個不同的執行計劃來公開有問題的數據 - 第一個查詢可以正常工作,而不會遇到麻煩的行,這純粹是運氣。

你可以包含你的表格模式嗎?如果你知道有問題的列,可以通過明確在JOINDATETIME列轉換爲VARCHAR(即FROM a JOIN b ON a.string_col = CONVERT(VARCHAR(25), b.date_col, 120),或任何形式爲宜)修復轉換問題,所以發動機不會嘗試做周圍用另一種方式並失敗。

+0

我不可能改變模式。這是針對ERP系統的。 [這個評論](http://stackoverflow.com/questions/26474647/mssql-query-fails-when-using-top-or-order-by/26474756#comment41587177_26474647)應該解釋它。你還需要架構嗎?這是相當大的... – MattAitchison 2014-10-20 21:08:35

+0

如果你知道有問題的列,模式是不需要的。 – 2014-10-20 21:14:23

+0

我以爲你建議在第一次閱讀時修改模式。哎呀! – MattAitchison 2014-10-20 21:17:28

1

的問題是,優化引擎將某個懶得看它的轉換之前,WHERE。在過去,您必須進行子查詢才能選擇具有正確類型的項目,然後在外部選擇中進行強制轉換(可能會更慢)。

但是,較新版本的SQL包括TRY_CAST。現在,您可以在連接語句中使用TRY_CAST。該函數在轉換失敗時返回null,因此它不會停止查詢運行該行的連接 - 這是所需的行爲。應該沒有使用它的問題。

像這樣:

SELECT  
    a.Company, a.FiscalYear, a.FiscalPeriod, a.JournalCode, a.JournalNum, a.JournalLine, a.Description, a.JEDate, a.GroupID, a.PostedBy, 
    a.PostedDate, a.SourceModule, b_1.PartDescription, b_1.PartNum, b_1.PONum, b_1.POLine, b_1.VendorID, b_1.VendorNum, b_1.VendorName 
FROM epicor905.dbo.GLJrnDtl AS a 
LEFT OUTER JOIN 
    (SELECT 
    a.Company, a.TranNum, a.TranDate, a.PartNum, a.WareHouseCode, a.TranQty, a.MtlUnitCost, a.ExtCost, a.PONum, a.POLine, a.PORelNum, 
    a.PartDescription, a.VendorNum, c.VendorID, c.Name AS VendorName, a.POUnitCost, a.POReceiptQty, a.GLTrans, a.PostedToGL, b.JournalNum, 
    b.JournalLine, b.JournalCode, b.FiscalYear 
    FROM epicor905.dbo.PartTran AS a 
    INNER JOIN epicor905.dbo.TranGLC AS b 
     ON a.Company = b.Company AND a.SysDate_ = TRY_CAST(b.Key1 AS DATE) AND a.SysTime = TRY_CAST(b.Key2 AS TIME) AND a.TranNum = b.Key3 
    LEFT OUTER JOIN epicor905.dbo.Vendor AS c 
     ON a.Company = c.Company AND a.VendorNum = c.VendorNum 
    WHERE 
    (b.RelatedToFile = 'PartTran') AND (a.PostedToGL = 1) 
) AS b_1 
    ON a.Company = b_1.Company 
    AND a.JournalCode = b_1.JournalCode 
    AND a.FiscalYear = b_1.FiscalYear 
    AND a.JournalNum = b_1.JournalNum 
    AND a.JournalLine = b_1.JournalLine 
WHERE  (a.FiscalYear = 2014) 

的利益部分:

... a.SysDate_ = TRY_CAST(b.Key1 AS DATE) AND a.SysTime = TRY_CAST(b.Key2 AS TIME) ... 

微軟參考文檔: http://msdn.microsoft.com/en-us/library/hh974669.aspx

+0

我剛剛嘗試過,但是因爲Sql Server 2008 R2不支持它,所以我不能使用'TRY_CAST'。 – MattAitchison 2014-10-22 01:17:59