Command contains unrecognized phrase/keyword in visual fox pro9 - sql

I am trying to join a 5 tables, using left outer join from ms sql server server using visual fox pro 9.
but I am getting this error "Command contains unrecognized phrase/keyword."
Here is my code.
SQLEXEC(lnConn4,"SELECT [TIARA$Sales Invoice Header].No_,;
[TIARA$Sales Invoice Header].[Sell-to Customer No_],;
[TIARA$Sales Invoice Header].[Bill-to Name],;
[TIARA$Sales Invoice Header].[Bill-to Address],;
[TIARA$Sales Invoice Header].[Posting Date],;
[TIARA$Sales Invoice Header].[VAT Registration No_],;
[TIARA$Sales Invoice Header].[External Document No_],;
[TIARA$Sales Invoice Header].[Shortcut Dimension 1 Code],;
[TIARA$Sales Invoice Header].[Bill-to City],;
[TIARA$Sales Invoice Line].No_,;
[TIARA$Sales Invoice Line].Description,;
[TIARA$Sales Invoice Line].[Unit of Measure],;
[TIARA$Sales Invoice Line].Quantity,;
[TIARA$Sales Invoice Line].[Unit Price],;
[TIARA$Sales Invoice Line].[VAT %],;
[TIARA$Sales Invoice Line].[Line Discount %],;
[TIARA$Sales Invoice Line].[Amount Including VAT],;
[TIARA$Sales Invoice Line].[Invoice Price],;
[TIARA$Sales Invoice Line].Amount,;
TIARA$Item.[Manufacturer Code],;
TIARA$Customer.[Territory Code],;
[TIARA$Sales Shipment Header].Note,;
[TIARA$Sales Shipment Header].[Order No_],;
[TIARA$Sales Shipment Header].No_;
FROM [TIARA$Sales Invoice Header];
LEFT OUTER JOIN [TIARA$Sales Invoice Line];
ON [TIARA$Sales Invoice Header].No_ = [TIARA$Sales Invoice Line].[Document No_];
LEFT OUTER JOIN TIARA$Item;
ON [TIARA$Sales Invoice Line].No_ = TIARA$Item.No_;
LEFT OUTER JOIN TIARA$Customer;
ON [TIARA$Sales Invoice Line].[Sell-to Customer No_] = TIARA$Customer.No_;
LEFT OUTER JOIN [TIARA$Sales Shipment Header];
ON [TIARA$Sales Invoice Header].[Order No_] = [TIARA$Sales Shipment Header].[Order No_];
WHERE [TIARA$Sales Invoice Header].No_ = THISFORM.TEXT1.TEXT;
ORDER BY [TIARA$Sales Invoice Header].[Posting Date] DESC;
INTO TABLE c:\tiarasys\temp\invoice")

If you want to create a multi-line string in Vfp, you can for example use Text/Endtext, e.g.
LOCAL lcSql
TEXT TO lcSql
SELECT col1,
col2,
col4
From ...
Left Join....
Where ...;
EndText
SQLEXEC(lnConn4,m.lcSql,...)
But if you want to send that string via ODBC, you would need to talk the Server slang, e.g. T-SQL for MS Sql Server, i.e. remove the FoxPro line-continuation ";" characters, and the Into Table part, everything the server would not understand.
And if the server does not understand, the SqlExec() function would return -1, and you can use Vfp's AError() function to get the ODBC error message.

Stefan is right that putting the whole query right into SQLExec() isn't a good idea.
That said, one problem here is the INTO TABLE clause at the end. That's not going to work in SQL Server and it isn't helpful. You want SQLExec() to give you back a cursor, which is what it does by default. If you really want to create a table from that cursor, you can with COPY TO, but usually you just work with the cursor.
Another problem is the reference to a textbox inside the quotes where you're building the query. That's going to just put that exact string in your query, not the textbox value.
Anyway, take Stefan's advice and then you can look at the query you've built and if the problem hasn't gone away, you'll be able to see what might be causing trouble.

Here your real problem, causing the error is the literal strings are limited to 255 characters in length. Your SQL command string literal is over 255.
Either divide that into pieces where each literal is 255 characters at most
Or write it within TEXT ... ENDTEXT block as Stefan suggested.
To expand on it:
clear
x = "12345678901234567890123456789012345678901234567890;
12345678901234567890123456789012345678901234567890;
12345678901234567890123456789012345678901234567890;
12345678901234567890123456789012345678901234567890;
12345678901234567890123456789012345678901234567890;
12345678901234567890123456789012345678901234567890"
? m.x, LEN(m.x)
Would fail with the error you get. However, if you divide it into smaller pieces then you can concatenate to build up a string variable (up to 16 Mb according to documentation):
x = "12345678901234567890123456789012345678901234567890;
12345678901234567890123456789012345678901234567890;
12345678901234567890123456789012345678901234567890;
12345678901234567890123456789012345678901234567890"+;
"12345678901234567890123456789012345678901234567890;
12345678901234567890123456789012345678901234567890"
? m.x, LEN(m.x)
Of course especially for SQL commands it is preferable to use TEXT...ENDTEXT. It has a big advantage of that you can copy paste the text content into SSMS and test your code there.
Then, the hidden error is INTO TABLE ... as Tamar pointed out. You can't create an on disk table like that using SQLExec(). Instead you would use the 3rd parameter to get the result into a cursor and then you can write to a table as you did from that cursor. ie:
SQLExec(m.myHandle, "select * from myTable", "crsResult")
Select * from crsResult into table ('c:\MyFolder\myTable')
Tamar also mentioned about referring text objects on form, for them you would use parameters in your code. ie:
myValue = thisfrom.txtSomething.Value
SQLExec(m.handle, "select * from myTable where myField = ?m.myValue", "crsResult")
And then to last probable error, your code sounds to be querying Excel tables? If so then that might be the wrong SQL for Excel (MSAccess engine doesn't really understand good ANSI SQL). If that happens to be the case, try using a pair of parentheses around each of your joins.

SQLEXEC(lnConn4,"Select [Posting Date],;
[Bill-to Name],;
[VAT Registration No_],;
[Bill-to City],;
No_,;
[Order No_],;
[Bill-to Address],;
[Shortcut Dimension 1 Code];
from [TIARA$Sales Invoice Header];
where No_ = ?inv;
order by [Posting Date] desc")
COPY TO C:\Tiarasys\Temp\invoice_header
SELECT 1
USE C:\Tiarasys\Temp\invoice_header EXCLUSIVE ALIAS invoice_header
orno = Order_no_
SQLEXEC(lnConn4, "Select [Unit of Measure],;
Quantity,;
No_,;
[Document No_],;
[Unit Price],;
[Sell-to Customer No_],;
Amount,;
[Amount Including VAT] from [TIARA$Sales Invoice Line];
where [Document No_] = ?inv")
COPY TO C:\Tiarasys\Temp\invoice_line
SELECT 2
USE C:\Tiarasys\Temp\invoice_line SHARED ALIAS invoice_line
sellno = Sell_to_cu
num = No_
SQLEXEC(lnConn4, "Select No_,;
[Manufacturer Code] from TIARA$Item;
where No_ = ?num")
COPY TO C:\Tiarasys\Temp\items
SELECT 3
USE C:\Tiarasys\Temp\items EXCLUSIVE ALIAS items
SQLEXEC(lnConn4, "Select No_,;
[Territory Code] from TIARA$Customer;
where No_ = ?sellno")
COPY TO C:\Tiarasys\Temp\customer
SELECT 4
USE C:\Tiarasys\Temp\customer EXCLUSIVE ALIAS customer
SQLEXEC(lnConn4, "Select No_,;
[Order No_],;
Note,;
[Sell-to Customer No_] from [TIARA$Sales Shipment Header];
where[Order No_] = ?orno")
COPY TO C:\Tiarasys\Temp\shipment_header
SELECT 5
USE C:\Tiarasys\Temp\shipment_header EXCLUSIVE ALIAS shipment_header

Related

How to add 2nd price column in SQL when info is normally stored on 2 separate rows

I currently have a very simple SQL script, which provides the sell price for a special customer of ours, who gets Priceline "J". I'd like to add a column of Retail pricing as well for them to reference, which is normally Priceline "R". My query currently looks like this:
SELECT RS_PCL.SKU,
RS_PCL.SKU_DESC,
RS_PCL.PACKAGE,
RS_PCL.PRICE AS [Sell Price],
RS_PCL.STD AS [Start Date],
RS_PCL.END AS [End Date]
FROM RS_PCL
WHERE RS_PCL.PRICELINE = "J"
Would anyone be able to help me figure out how I could add the "R" price line as another column instead of separate rows?
I can add WHERE RS_PCL.PRICELINE IN ("J","R") but it would create a separate row for each Retail price, instead of in the column next to it. I've seen examples of a separate SELECT CASE WHEN, but not sure exactly how the syntax works.
The prices are always going to have the same start date, so it would just need to join where the SKU matches and the Start Date matches.
NOTE : IM sorry I accidentally edited your answer, not my question...
Revised: Running into errors with this code still, saying "Your query does not include the specified expression 'GL Type' as part of an aggregate function" or would say each field that isn't included in the group by clause
SELECT RS_PCL.[GL Type],
RS_PCL.SKU,
RS_PCL.[SKU Desc],
RS_PCL.Supplier,
RS_PCL.[Case UPC],
RS_PCL.[Pack UPC],
RS_PCL.[Unit UPC],
RS_PCL.PDCN,
RS_PCL.Package,
RS_PCL.[Price Start Date],
RS_PCL.[Price End Date],
Iif( RS_PCL.PRICELINE = "J" , RS_PCL.Price , Null) AS [Sell Price],
Iif( RS_PCL.PRICELINE = "R" , RS_PCL.Price , Null) AS [Retail Price],
RS_PCL.Cost,
RS_PCL.Tax,
RS_PCL.Freight
FROM RS_PCL
WHERE (RS_PCL.PRICELINE IN ("J","R"))
Tested the Self Join query listed below, I keep getting a "Syntax Error in FROM Clause" with this query.
SELECT J.*, R.R_PRICE FROM RS_PCL AS J
INNER JOIN SELECT (RS_PCL.SKU, RS_PCL.[Price Start Date], RS_PCL.Price AS R_PRICE FROM RS_PCL WHERE RS_PCL.PRICELINE = "R") AS R
ON J.SKU = R.SKU AND J.[Price Start Date] = R.[Price Start Date]
WHERE RS_PCL.Priceline = "J"
SELECT CASE does not work in Access query. Use IIf() or Switch() or Choose().
Perhaps a CROSSTAB query or emulate CROSSTAB with expressions to create fields. Presuming, as indicated in question title, there is one "J" and one "R" record for each data combination:
SELECT SKU, SKU_DESC, PACKAGE, STD, END,
Max(IIf(PRICELINE = "J", PRICE, Null)) AS J,
Max(IIf(PRICELINE = "R", PRICE, Null)) AS R
FROM RS_PCL
GROUP BY SKU, SKU_DESC, PACKAGE, STD, END
Or a self-join, assuming only fields needed as unique identifier are SKU and STD:
SELECT J.*, R.R_PRICE FROM RS_PCL AS J
INNER JOIN (SELECT SKU, STD, PRICE AS R_PRICE FROM RS_PCL WHERE PRICELINE = "R") AS R
ON J.SKU = R.SKU AND J.STD = R.STD
WHERE PRICELINE = "J";
This would be useful on a report but useless for a data entry form.
Yet another approach would use DLookup() domain aggregate function. Domain aggregate function can cause slow performance in query or form but the dataset would be editable.

Optimize Images retrieval from database

I have two tables in a database which are "Setup" and "Items". "Setup" contain an image column with a data type of varbinary(max) and about 21 rows of records and "Items" also contains 12000 records. "Setup" table joins with "Items" table. The problem is when I run my join query with Image in it, it takes about 2 minutes but if I take the image column out of the query it takes 0 seconds. And if I maintain the image column but change the data type of image column to varbinary(1000) it takes 0 seconds. I want to use varbinary(max) as a data type for image column and execute the query in 0 seconds.
This is my query:
SELECT PS.[Item Image], P.[ItemId], P.SetupId, PS.Consumable, PS.Category,
PS.[Description], PS.Brand, PS.[Item Name], P.[Serial #], P.[Vendor Name],
P.[Date Received], [Location], S.[State] AS [Item State], Location
FROM PHOTOMATICS AS P
INNER JOIN PHOTOMATICSETUP AS PS
ON PS.[SetupId] = P.SetupId
LEFT JOIN PHOTOMATICSTATE AS S
ON S.PhotomaticId = P.ItemId ORDER BY P.ItemId

Need MS Access Form Field to automatically Calculate and Allocate Costs based on given Parameters

Below is my mock database that I am using. I have four different tables: Tbl_MainDatabase, Tbl_InsuranceCoverage, Tbl_MatterDetail, and Tbl_PaymentProcessing.
What I want -
I want my form to determine the remaining Retention Limit (i.e., Retention Limit for the applicable policy - sum of invoices for the same Claim Number )
According to the mock database, the required answer should be [ $2500 - (300+700+355)] as highlighted for your convenience
What I tried
I used the help of Graphical representation through the following query:
SELECT [Claim Number], Sum([Net Invoice Amount])
FROM [PaymentProcessing]
GROUP BY [Claim Number]
This method works to show me how much I spent per claim number so far in the form of a graph. However I want to display the remaining amount.
Any Help is appreciated :)
I am one month old at using Access. But I am trying my best to learn
Thank you in advance!
SELECT
IC.[Retention Limit]-SUM([Net Invoice Amt]) AS Remaining, MD.[Claim Number], IC.[Retention Limit], IC.InsuranceID
FROM tbl_InsuranceCoverage IC
INNER JOIN tbl_MatterDetail MD ON ic.InsuranceID = MD.Policy
INNER JOIN tbl_PaymentProcessing PP ON MD.MatterDetailID=pp.MatterDetailID AND MD.[Claim Number]=pp.[Claim Number]
GROUP BY MD.[Claim Number], IC.[Retention Limit], IC.InsuranceID
See if this works. Havent tested it but seems simple. You can remove the extra columns, but this will hlep you understand joins a bit
For All the New users The above code by #Doug Coats works perfectly.
Make Sure All the Foreign Key and Primary Keys is linked in the Relationship Property. ( One of the way To do this in the Query is - Right click on the Query and select Design View --> Right click again on the grey space and Select Show all Tables Now Drag your Primary Key of the table and drop at the foreign Key on the other table --> This will create a relationship between both for the Query Purpose.
This will also Prevent Data from Duplication in the query then use a similar code as described by Doug Coats in the above comment in the SQL View
SELECT [Insurance Coverage].[Retention Unit]-Sum([Net Invoice Amount]) AS Remaining, [Matter Detail].[Claim Number], [Insurance Coverage].[Retention Unit], [Matter Detail].Policy
FROM (([Main Database] INNER JOIN [Matter Detail] ON [Main Database].[Database ID] = [Matter Detail].[Short Name]) INNER JOIN [Payment Processing] ON ([Matter Detail].[Matter Detail ID] = [Payment Processing].[Matter Detail ID]) AND ([Main Database].[Database ID] = [Payment Processing].[Short Name])) INNER JOIN [Insurance Coverage] ON [Matter Detail].Policy = [Insurance Coverage].[Insurance ID]
GROUP BY [Matter Detail].[Claim Number], [Insurance Coverage].[Retention Unit], [Matter Detail].Policy;
You can then display this query in the form - I am still evaluating best way to display this query probably in a Combo Box (Not sure if any other controls has a row source)
Thank you

Filling not existing data with 0 SQL / Access

Please see below explanation of my problem. I have 2 tables.
[TABLE1: LocationsOFproducts - Keep data about location of products and quantity][1]
[TABLE2: Datahistory - keep data about stock movement ( removing/adding product from/to stock )][2]
[QUERY1: SumDataHistoryQuery - Making Sum of Products moved from the same location][3]
QUERY2: TOTAL QTY - Counting how many products left in some location after stock movement
SQL Code:
SELECT LocationsOFproducts.[Bay no]
,LocationsOFproducts.[Product Code]
,LocationsOFproducts.LocationQTY
,SumDatahistoryQuery.SumOfQTY
,([LocationQTY]) + ([SumOfQTY]) AS TOTALQTY
FROM LocationsOFproducts
INNER JOIN SumDatahistoryQuery ON (LocationsOFproducts.[Product Code] = SumDatahistoryQuery.[Product Code])
AND (LocationsOFproducts.[Bay no] = SumDatahistoryQuery.[Bay no])
AND (LocationsOFproducts.[Product Code] = SumDatahistoryQuery.[Product Code])
GROUP BY LocationsOFproducts.[Bay no]
,LocationsOFproducts.[Product Code]
,LocationsOFproducts.LocationQTY
,SumDatahistoryQuery.SumOfQTY
,([LocationQTY]) + ([SumOfQTY])
ORDER BY LocationsOFproducts.[Product Code];
RESULT:
I expect a little bit different result.
My query should check is there any more value with Bay no,product code and QTY in Datahistory table, if not I want to fill that space with data from LocationOfproducts table and in the field SumOfQTY fill those
values with 0 to make a sum in TOTALQTY column.
Please see below what I need to get:
Please see query what I need to get - I maked that in Photoshop by cutting and pasting fields:
Can anyone know how to write the right query?

SQL query to report on what invoices have not been paid, ordered by invoice number

new to SQL and only been doing it for a week and a half. So I apologise now for the question being simple or appearing to be stupid.
I want to present a report on invoices that have not been paid by a given date, ordered by invoice number.
This is how I have displayed, the paid invoices but without the given date.. How do I display, the invoices that have not been paid by say 31-MAR-14.
SELECT INVOICE.INVOICE_NUMBER, INVOICE.INVOICE_DATE, PAYMENT.PAYMENT_NO, PAYMENT.INVOICE_NUMBER
FROM INVOICE, PAYMENT
WHERE INVOICE.INVOICE_NUMBER = PAYMENT.INVOICE_NUMBER
ORDER BY INVOICE.INVOICE_NUMBER;
SELECT PAYMENT.PAYMENT_NO
FROM INVOICE, PAYMENT
WHERE INVOICE.INVOICE_NUMBER = PAYMENT.INVOICE_NUMBER
AND INVOICE.INVOICE_DATE = 'AAAAMMJJ'
ORDER BY INVOICE.INVOICE_NUMBER;
Try something like this.
I have question. How do you say the invoice are not paid ?
You need to join the two tables together with a LEFT JOIN, then look to see where the payment date is > 31-MAR-14. Try something like this:
SELECT INVOICE.INVOICE_NUMBER, INVOICE.INVOICE_DATE, PAYMENT.PAYMENT_NO, PAYMENT.INVOICE_NUMBER
FROM INVOICE
LEFT JOIN PAYMENT ON INVOICE.INVOICE_NUMBER = PAYMENT.INVOICE_NUMBER
WHERE PAYMENT.Date_of_payment > '3/31/2014'
ORDER BY INVOICE.INVOICE_NUMBER;
This looks for all payments that were made after 3/31/2014. You may need to add another condition, that limits what invoices you're looking for.
To check payments that have not been made, look where any field in the PAYMENT table is null. SQL like this:
SELECT INVOICE.INVOICE_NUMBER, INVOICE.INVOICE_DATE, PAYMENT.PAYMENT_NO, PAYMENT.INVOICE_NUMBER
FROM INVOICE
LEFT JOIN PAYMENT ON INVOICE.INVOICE_NUMBER = PAYMENT.INVOICE_NUMBER
WHERE INVOICE.INVOICE_DATE = '3/31/2014'
AND PAYMENT.PAYMENT_NO IS NULL
ORDER BY INVOICE.INVOICE_NUMBER;
LEFT JOIN in this case will always return values for the INVOICE table, but may return NULL values in place of the PAYMENT if a payment has not been entered yet. Checking AND PAYMENT.PAYMENT_NO IS NULL will tell you that a payment has not been made yet.