Navision Stat udviklingsblog
Denne blog indeholder vejledninger og codesnippets i C/AL, PowerShell, SQL, m.fl., som bliver anvendt i det daglige arbejde med at udvikle og vedligeholde Navision Stat. Bloggen er på engelsk og henvender sig til NAV-udviklere.
Introduction
The Navision Stat Development Team resides at the Agency for Public Finance and Management, as part of the Ministry of Finance in Denmark. We support and develop Microsoft Dynamics NAV2016CU12 supporting multitenancy and releasing updates monthly to all governmental organisations.
This blog contains walkthroughs, instructions and codesnippets in C/AL, PowerShell, SQL, etc. which document the solutions to some of the many big and small challenges we meet in our ongoing effort to improve and optimize Microsoft Dynamics NAV.
Blog Content
- Execute SQL query from NAV
- How to retrieve name of NAV database, server, service etc.
- How to identify white spaces with SQL
- How to work with multiple NAV versions
- Prevent NAV 2013r2 from starting a new client session when running an object
- From multitenancy to singletenancy
- Delete NAV users with SQL
- SMTP - Files are created but are not sent
- Convert data in all NAV companies
- Find name of NAV server (service) using GETURL
All content provided on this blog is for informational purposes only. The Navision Stat team makes no representations as to the accuracy or completeness of any information on this site or found by following any link on this site. The Navision Stat team will not be liable for any errors or omissions in this information nor for the availability of this information.
Execute SQL query from NAV
NAV2016 - 4Apr2017: We recently needed to create an object to query the SQL database directly from NAV. The method used to query the SQL database from NAV had to be another method than ADO, as we support multiple hosting environments that by default do not contain the .NET framework ADODB.ConnectionClass. Instead, we wanted to use the namespace System.Data.SQLClient, which is the .NET framework Data Provider for SQL Server.
We use the DotNet datatypes SqlConnection, SqlCommand, and SQLDataReader to connect, query, and retrieve data from a given SQL database to NAV:
- System.Data.SqlClient.SqlConnection
- System.Data.SqlClient.SqlCommand
- System.Data.SqlClient.SqlDataReader
The CodeUnit in this post is a small part of a bigger project concerning identifying white spaces in the database. But in the example given, we just query the Vendor table and retrieve 5 vendor names, so as to give a simple example of how to use the namespace System.Data.SQLClient. The object shown in this post has been tested and works in both NAV2013R2 and NAV2016.
- Download the .fob file of the object (fob)
- Download the .txt file of the object (txt)
Example
Below is an extract of the CodeUnit. Notice that you have to add the name of the server and database in use - it is hardcoded for simplicity (see our other post regarding how to retrieve the server and database name).
ExecuteSQLcommand()
//DatabaseName and ServerName (hardcoded for simplicity)
g_DatabaseName:= 'MyDatabase'; //Update before running the codeunit
g_ServerName:= 'MyServer'; //Update before running the codeunit
//Retrieve and remove special characters from the company name
l_CompanyName:= CONVERTSTR(COMPANYNAME,'."\/''%][','________');
//Define the table to query and the query itself (hardcoded for simplicity)
l_TabelName:= '$Vendor';
l_SQLquery:= 'SELECT top 5 No_, Name ' +
'FROM [' + g_DatabaseName + '].[dbo].[' + l_CompanyName + l_TabelName + ']' +
'WHERE Name <> ''''';
//Create and open SQN connection, run the SQL query, and store the query result in SQLDataReader
GetSQLConnection(l_SQLConnection);
l_SQLConnection.Open;
l_SQLCommand:= l_SQLCommand.SqlCommand(l_SQLquery,l_SQLConnection);
l_SQLCommand.CommandTimeout(0);
l_SQLDataReader:= l_SQLCommand.ExecuteReader;
//Check if the query returned any values
IF l_SQLDataReader.HasRows THEN BEGIN
MESSAGE(STRSUBSTNO('At least one record returned from the query'));
END ELSE BEGIN
MESSAGE(STRSUBSTNO('No records returned from the query'));
END;
//Loop through records returned from the query and inform
WHILE l_SQLDataReader.Read DO BEGIN
l_Counter := l_Counter + 1;
MESSAGE(STRSUBSTNO('Record %1 of 5: \\ID: %2 \Name: %3',l_Counter, l_SQLDataReader.GetValue(0), l_SQLDataReader.GetValue(1)));
END;
//Always close connection again
l_SQLConnection.Close;