linked server "SAGE" returned message "[ProvideX][ODBC Driver]Expected lexical element not found: <identifier>".

SOLVED

I have this query returning the error message. Any idea?

SELECT  A.SalesOrderNo,
B.UDF_COMPLETE_PART,
B.UDF_CUST_PART,
E.ExtendedDescriptionText,
B.UDF_Serial,
A.CustomerPONo,
A.UDF_EXT_CUST_PO,
A.ARDivisionNo,
D.CustomerNo,
D.CustomerName,
A.ConfirmTo,
A.EmailAddress,
A.UDF_END_USER,
A.UDF_REG_MANAGER,
A.UDF_REP_ACCT,
A.BillToName,
A.BillToCity,
A.BillToState,
A.ShipToName,
A.ShipToCity,
A.ShipToState,
C.CountryName,
A.RMANo,
F.ReceiptDate   
FROM        
{SO_SalesOrderHistoryHeader A   
inner join SO_SalesOrderHistoryDetail B on A.SalesOrderNo = B.SalesOrderNo    
inner join AR_Customer D on A.CustomerNo = D.CustomerNo and A.ARDivisionNo = D.ARDivisionNo        
inner join SY_Country C on C.CountryCode = D.CountryCode        
inner join CI_ExtendedDescription E on B.ExtendedDescriptionKey = E.ExtendedDescriptionKey        
Left join RA_ReceiptsHistoryHeader F on A.RMANo = F.RMano}
WHERE       
A.orderstatus = ''A''')

  • 0

    Try replacing every thing from FROM to the end of the statement with the below.

    FROM
    SO_SalesOrderHistoryDetail B, SY_Country C, AR_Customer D,CI_ExtendedDescription E,
    {oj RA_ReceiptsHistoryHeader F LEFT OUTER JOIN SO_SalesOrderHistoryHeader A ON A.RMANo = F.RMANo}

    WHERE

    A.SalesOrderNo = B.SalesOrderNo AND
    A.ARDivisionNo = D.ARDivisionNo AND
    A.CustomerNo = D.CustomerNo AND
    C.CountryCode = D.CountryCode AND
    B.ExtendedDescriptionKey = E.ExtendedDescriptionKey AND
    A.orderstatus = 'A'

    John Nichols

    Sage

  • 0 in reply to jcnichols

    The query returns this error message:

    OLE DB provider "MSDASQL" for linked server "SAGE" returned message "[ProvideX][ODBC Driver]Timeout expired.".

  • 0

    The ProvideX ODBC driver doesn't use the standard syntax for table joins.

    Refer to the attached document for more info on its usage.

    6886.PVX-ODBC4x.pdf

    You did mention linked server so i don't recall specifically whether SSMS expects its T-SQL syntax or if you have to use the PVX SQL syntax which uses some variant of the SQL-92 standard if i recall correctly.

    Moving along, in order to join tables, you have to use a {oj keyword in the join and you can't join more than one table per {oj keyword, you have to duplicate common joins and then use the WHERE clause to join the common tables together. In most cases, if you have  abunch of tables using inner joins, you can get away with not including the {oj keyword in the FROM clause and just list each table followed by its alias with commas separating each table and then use the WHERE clause to join them all to together.

    If you must include any kind of outer join, you must include the {oj keyword and the ON keyword in the join. Here is a basic example.

    SELECT * 
    FROM 
    {oj 
    CI_Item CII 
    Left Outer Join 
    SO_SalesOrderDetail SOD 
    On 
    ( 
    CII.ItemCode = SOD.ItemCode
    )
    }

    Keep in mind that any fields from a table joined as the outer join included in the WHERE clause will produce Inner Join results.

    If you have more than two tables involved and need an outer join between two of them, you can use the WHERE clause to handle the common joins to produce the inner joins and use the {oj join for the two tables that are needed in the outer join. Here is another basic example of this.

    SELECT * 
    FROM 
    SO_SalesOrderHeader SOH, 
    {oj 
    SO_SalesOrderDetail SOD 
    Left Outer Join 
    PO_PurchaseOrderHeader POH 
    ON 
    ( 
    SOD.PurchaseOrderNo = POH.PurchaseOrderNo 
    ) 
    } 
    WHERE 
    SOH.SalesOrderNo = SOD.SalesOrderNo 
     

  • 0 in reply to Dona2802

    If your history tables have a lot of records (200k+), then including this many historical tables probably isn't going to work out for you. 

    On another note, what is the end goal of you query?

    1. Show all sales orders regardless of whether or not they have an RMA recorded against them and if they do, show the receipt date?
    2. Show only sales orders that have an RMA recorded against them and show the receipt date? This is what John's suggestion will return.

    If you do have a bunch of historical records across the tables,you may be better off copy each table individually to a mirror table in your SQL database and then use those as your source tables allowing you use T-SQL.

  • 0 in reply to David Speck

    I'd do "select * ..." from queries as SQL Views, then do another query with the joins inside SQL on those Views (avoiding the complex Providex join syntax). 

    Unless you have a massive performance hit from pulling in unfiltered table data, that approach is much easier to deal with.

  • 0 in reply to Kevin M

    That is typically the best way to go if you have SSMS available, if not and you're dealing with the Standard or Advanced platforms and trying to add complicated joins to a crystal report that can't be handled with sub-reports, you don't have much choice unless you want to involve MS Access for passthrough queries or SQL Server Express if possible.

  • 0 in reply to David Speck

    I use SQL Express often, when dealing with complex joins in reports (and Providex data).

  • 0 in reply to Kevin M

    I'm using SQL Server 2014

  • 0 in reply to Dona2802
    verified answer

    Have you tried using unfiltered SQL Views (one table at a time), then doing the joins in SQL (based on the views) as I suggested?

    More common for me is to just use queries to refresh mirror tables (stored in SQL), but I don't see why linked server queries wouldn't work too.

  • 0 in reply to Kevin M

    I'll try this way. Thanks for your replay.