Discussion:
Complex database queries in Dexterity
(too old to reply)
Misa
2009-06-24 01:38:01 UTC
Permalink
Hi,

I am trying to retrieve some data from SQL database for GP integration with
Dexterity.

Currently I am trying to use sunScript "table" and "range".
When I need to retrieve data from GP default tables, I do not want to change
the structure of the table (such as keys and sort). As the result, I found it
difficult to get specific data with complex sql queries.

Now I found that I can use ADO and pass-through SQL.
If I use ADO, I use recordset to read each record.
If I use pass-throuhg SQL, I need to fetch the each record.

I am wondering what is the common way to read records with complex sql in
Dexterity. If there are any suggestions or advice, I would appriciate.

Thank you in advance.

Misa
Warner Alexander
2009-06-24 14:26:01 UTC
Permalink
I have successfully used 2 methods:

Use ADO when accessing a non-GP database. You can retrieve multiple records
in one query and step through the recordset.

Use the "range where" structure when accessing a GP database.
--
Warner
Post by Misa
Hi,
I am trying to retrieve some data from SQL database for GP integration with
Dexterity.
Currently I am trying to use sunScript "table" and "range".
When I need to retrieve data from GP default tables, I do not want to change
the structure of the table (such as keys and sort). As the result, I found it
difficult to get specific data with complex sql queries.
Now I found that I can use ADO and pass-through SQL.
If I use ADO, I use recordset to read each record.
If I use pass-throuhg SQL, I need to fetch the each record.
I am wondering what is the common way to read records with complex sql in
Dexterity. If there are any suggestions or advice, I would appriciate.
Thank you in advance.
Misa
Misa
2009-06-24 15:43:01 UTC
Permalink
Warner,

Thank you for the reply.

So you are suggesting that for GP database, I should use range where.
I use range where but it does not sort the records which is often required..
Post by Warner Alexander
Use ADO when accessing a non-GP database. You can retrieve multiple records
in one query and step through the recordset.
Use the "range where" structure when accessing a GP database.
--
Warner
Post by Misa
Hi,
I am trying to retrieve some data from SQL database for GP integration with
Dexterity.
Currently I am trying to use sunScript "table" and "range".
When I need to retrieve data from GP default tables, I do not want to change
the structure of the table (such as keys and sort). As the result, I found it
difficult to get specific data with complex sql queries.
Now I found that I can use ADO and pass-through SQL.
If I use ADO, I use recordset to read each record.
If I use pass-throuhg SQL, I need to fetch the each record.
I am wondering what is the common way to read records with complex sql in
Dexterity. If there are any suggestions or advice, I would appriciate.
Thank you in advance.
Misa
Mariano Gomez
2009-06-24 14:38:01 UTC
Permalink
Misa,

There are a number of methods:

1. range where statement

The range where statement allows you to retrieve data sets by applying
additional restrictions to a SQL table. You can build the where clause as
simple or as complex as needed.

range clear table RM_Customer_MSTR;
range table RM_Customer_MSTR where physicalname('Customer Name' of table
RM_Customer_MSTR) + " LIKE '%maxim%'";
fill window some_scrolling_window;
range clear table RM_Customer_MSTR;

2. Pass-through SQL and SQL_Execute()

You can always use pass-through SQL which will allow you to build entire SQL
statements whether dynamic or static. I believe this will suite your needs a
bit better. I recommend you search the Dexterity help file for the
SQL_Execute() function and check the examples.

3. ADO

This for me would be the last resort. The problem with ADO is to be able to
pass in the connection string. Unlike pass-through SQL, ADO requires you to
pass in the connection string. Unfortunately, this connection string needs to
be hardcoded into the application -- not a good practice.
--
Best regards,
--
MG.-
Mariano Gomez, MIS, MCP, PMP
Maximum Global Business, LLC
http://www.maximumglobalbusiness.com
The Dynamics GP Blogster at http://dynamicsgpblogster.blogspot.com
Post by Misa
Hi,
I am trying to retrieve some data from SQL database for GP integration with
Dexterity.
Currently I am trying to use sunScript "table" and "range".
When I need to retrieve data from GP default tables, I do not want to change
the structure of the table (such as keys and sort). As the result, I found it
difficult to get specific data with complex sql queries.
Now I found that I can use ADO and pass-through SQL.
If I use ADO, I use recordset to read each record.
If I use pass-throuhg SQL, I need to fetch the each record.
I am wondering what is the common way to read records with complex sql in
Dexterity. If there are any suggestions or advice, I would appriciate.
Thank you in advance.
Misa
Warner Alexander
2009-06-24 15:25:02 UTC
Permalink
Mariano,

You can simplify setting up the ADO connection string by utilizing ODBC Data
Sources. Include the ODBC source in the connection string so if something
changes, you change the ODBC and not the hard-coded connection string.
--
Warner
Post by Mariano Gomez
Misa,
1. range where statement
The range where statement allows you to retrieve data sets by applying
additional restrictions to a SQL table. You can build the where clause as
simple or as complex as needed.
range clear table RM_Customer_MSTR;
range table RM_Customer_MSTR where physicalname('Customer Name' of table
RM_Customer_MSTR) + " LIKE '%maxim%'";
fill window some_scrolling_window;
range clear table RM_Customer_MSTR;
2. Pass-through SQL and SQL_Execute()
You can always use pass-through SQL which will allow you to build entire SQL
statements whether dynamic or static. I believe this will suite your needs a
bit better. I recommend you search the Dexterity help file for the
SQL_Execute() function and check the examples.
3. ADO
This for me would be the last resort. The problem with ADO is to be able to
pass in the connection string. Unlike pass-through SQL, ADO requires you to
pass in the connection string. Unfortunately, this connection string needs to
be hardcoded into the application -- not a good practice.
--
Best regards,
--
MG.-
Mariano Gomez, MIS, MCP, PMP
Maximum Global Business, LLC
http://www.maximumglobalbusiness.com
The Dynamics GP Blogster at http://dynamicsgpblogster.blogspot.com
Post by Misa
Hi,
I am trying to retrieve some data from SQL database for GP integration with
Dexterity.
Currently I am trying to use sunScript "table" and "range".
When I need to retrieve data from GP default tables, I do not want to change
the structure of the table (such as keys and sort). As the result, I found it
difficult to get specific data with complex sql queries.
Now I found that I can use ADO and pass-through SQL.
If I use ADO, I use recordset to read each record.
If I use pass-throuhg SQL, I need to fetch the each record.
I am wondering what is the common way to read records with complex sql in
Dexterity. If there are any suggestions or advice, I would appriciate.
Thank you in advance.
Misa
Mariano Gomez
2009-06-24 15:53:01 UTC
Permalink
Warner,

That's a good point, however I also don't like this method because if the
DSN name changes you are back to the same issue.

Best regards,
--
MG.-
Mariano Gomez, MIS, MCP, PMP
Maximum Global Business, LLC
http://www.maximumglobalbusiness.com
The Dynamics GP Blogster at http://dynamicsgpblogster.blogspot.com
Post by Warner Alexander
Mariano,
You can simplify setting up the ADO connection string by utilizing ODBC Data
Sources. Include the ODBC source in the connection string so if something
changes, you change the ODBC and not the hard-coded connection string.
--
Warner
Post by Mariano Gomez
Misa,
1. range where statement
The range where statement allows you to retrieve data sets by applying
additional restrictions to a SQL table. You can build the where clause as
simple or as complex as needed.
range clear table RM_Customer_MSTR;
range table RM_Customer_MSTR where physicalname('Customer Name' of table
RM_Customer_MSTR) + " LIKE '%maxim%'";
fill window some_scrolling_window;
range clear table RM_Customer_MSTR;
2. Pass-through SQL and SQL_Execute()
You can always use pass-through SQL which will allow you to build entire SQL
statements whether dynamic or static. I believe this will suite your needs a
bit better. I recommend you search the Dexterity help file for the
SQL_Execute() function and check the examples.
3. ADO
This for me would be the last resort. The problem with ADO is to be able to
pass in the connection string. Unlike pass-through SQL, ADO requires you to
pass in the connection string. Unfortunately, this connection string needs to
be hardcoded into the application -- not a good practice.
--
Best regards,
--
MG.-
Mariano Gomez, MIS, MCP, PMP
Maximum Global Business, LLC
http://www.maximumglobalbusiness.com
The Dynamics GP Blogster at http://dynamicsgpblogster.blogspot.com
Post by Misa
Hi,
I am trying to retrieve some data from SQL database for GP integration with
Dexterity.
Currently I am trying to use sunScript "table" and "range".
When I need to retrieve data from GP default tables, I do not want to change
the structure of the table (such as keys and sort). As the result, I found it
difficult to get specific data with complex sql queries.
Now I found that I can use ADO and pass-through SQL.
If I use ADO, I use recordset to read each record.
If I use pass-throuhg SQL, I need to fetch the each record.
I am wondering what is the common way to read records with complex sql in
Dexterity. If there are any suggestions or advice, I would appriciate.
Thank you in advance.
Misa
David Musgrave [MSFT]
2009-06-25 03:43:31 UTC
Permalink
Hi Misa

If you want to stay within native Dexterity code I would suggest using the range table where command

Look at these KB articles listed on the http://blogs.msdn.com/developingfordynamicsgp/pages/dexterity-articles.aspx page

How to write "Passthrough" SQL statements and "Range Where" clauses in Microsoft Great Plains Dexterity (KB 910129)
https://mbs.microsoft.com/knowledgebase/KBDisplay.aspx?scid=kb;en-us;910129

How to use a "Range Where" clause that is based on more than one table in Dexterity in Microsoft Dynamics GP (KB 922056)
https://mbs.microsoft.com/knowledgebase/KBDisplay.aspx?scid=kb;en-us;922056

Also look at the assign as key command which allows you to create keys on-the-fly which can then be used with standard
ranges.

If you are happy to write native SQL, then just use the passthrough SQL commands, see the example for the SQL_Execute()
command in the Dex help file.

David Musgrave [MSFT]
Escalation Engineer - Microsoft Dynamics GP
Microsoft Dynamics Support - Asia Pacific

Microsoft Dynamics (formerly Microsoft Business Solutions)
http://www.microsoft.com/Dynamics

mailto:***@online.microsoft.com
http://blogs.msdn.com/DevelopingForDynamicsGP

Any views contained within are my personal views and not necessarily Microsoft policy.
This posting is provided "AS IS" with no warranties, and confers no rights.
Boun Phommarath
2009-07-09 16:10:01 UTC
Permalink
Here's a good trick that I've used in the past with good success.

Suppose you want to do some complex joins, sorting and filtering on multiple
tables from various sources (i.e. GP, 3rd Party GP app and an outside
application).

GPTable has fields Field1 and Field2
3rdPartyTable has fields Field1 and Field3
OutsideTable has fields Field1 and Field4

Suppose you want join all 3 tables together where Field1="Bob".

1. Create a temp table (e.g. TempTableX) in your Dex application with fields
Field1, Field2, Field3, Field4. Create keys for that table for whatever
sorting you need.

2. Create a Function in your Dex application to fill the temp table.

Function: FillTempTable
function returns integer ErrorCode;
inout table TempTableX;
in string iField1Value;

local text sqltext;
local long lConn;
local string lTableName;

SQL_Connection(lConn);

{Clear content of the temp table and get it ready to receive new data}
range clear table TempTableX;
remove range TempTableX;

{Get the name of the temp table in SQL. Temp tables are created as needed
and are named differently in SQL every time}
lTableName = Table_GetOSName(table TempTableX);

{Build your complex SQL statement to populate the temp table. This statement
can be as complex and as simple as you want. This example simply joins the 3
tables together.}
sqltext =
"insert into " + lTableName +
"(Field1, Field2, Field3, Field4) +
"select T1.Field1, T1.Field2, T2.Field3, T3.Field4
from " + + " as T1
left join (select * from 3rdPartyTable) as T2
on T1.Field1=T2.Field1
left join (select * from OutsideTable) as T3
on T1.Field1=T3.Field1
where T1.Field1='" + iField1Value + """;
SQL_Execute(lConn, sqltext);

The table has been properly filled with data. There are several advantages
to this.
1. Only data that you want is in the temp table. No need to set any range or
filter.
2. All the leg work was done by the server because the filling of the table
was done by SQL. If you had to do this in Dexterity, you would need 3 nested
loops to gather all the data. This is extremely slow because every row of
data is moving thru the network twice (Reading cause data to be sent from SQL
to the local machine and writing the data to the temp table causes the data
to be sent back to thru the network to SQL). With more and more tables and
business logics involve, the iterative approach becomes exponentially more
complicated and slow.
3. More access to more tables. You are not restricted to tables within the
GP world only.
4. After you temp table is filled, you can further leverage conventional Dex
table ranging and filtering capabilities.
5. Makes for easy reporting. Report Writer is a nightmare to work with if
you are trying to build a complex report. Let SQL prep the data into the temp
table and then just dumb dump it onto a simple report.

To fill the table simply call:

FillTempTable(table TempTableX, "Bob");

get first table TempTableX;
while (err()=OKAY) do
{Do stuff}

get next table TempTableX;
end while;
Post by Misa
Hi,
I am trying to retrieve some data from SQL database for GP integration with
Dexterity.
Currently I am trying to use sunScript "table" and "range".
When I need to retrieve data from GP default tables, I do not want to change
the structure of the table (such as keys and sort). As the result, I found it
difficult to get specific data with complex sql queries.
Now I found that I can use ADO and pass-through SQL.
If I use ADO, I use recordset to read each record.
If I use pass-throuhg SQL, I need to fetch the each record.
I am wondering what is the common way to read records with complex sql in
Dexterity. If there are any suggestions or advice, I would appriciate.
Thank you in advance.
Misa
Loading...