SQL Snippet: Get Dates for Accruals

Microsoft SQL ServerAs I’ve mentioned before I write a fair bit of SQL code for various projects or support calls and will be posting some of it here.

I recently created a report for a client to use to extract transaction lines to use to import as an accruals journal; as part of the extract I worked out the last day of the one month and the first day of the next to use as the transaction and reversing dates on the journal.

The scripts below has versions for both before and after SQL 2012 (with the introduction of the EOMONTH function in 2012, getting these dates became easier).

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/
-- set date variable
DECLARE @Date DATETIME = GETDATE()

-- get last date of this month
SELECT CONVERT(VARCHAR(10), DATEADD(month, ((YEAR(@Date) - 1900) * 12) + month(@Date), -1), 126)

-- get last date of this month in SQL 2012
SELECT EOMONTH(@Date)

-- get first date of next month
SELECT CONVERT(VARCHAR(10), DATEADD(month, DATEDIFF(month, 1, DATEADD( month, 1, @Date )), 0), 126)

-- get first date of next month in SQL 2012
SELECT DATEADD(day, 1, EOMONTH(@Date))

SQL Script to Disable Business Analyzer Fact Pane

Microsoft Dynamics GPWhen the Reporting Tools are deployed for Microsoft Dynamics GP a fact pane is enabled in the navigation lists, which gives access to the reports. However, this also causes the navigation lists to be much slower. In some cases, pretty much unusable.

While users can switch off the fact pane on navigation lists, they need to be disabled by each user on each list. This means people don;t actually use them.

It is possible, however, to disable the lists using some SQL against the system database (by default called DYNAMICS.

When a user opens a navigation list for the first time, an entry is made to the List View Options (SY07225) table. The first script inserts a trigger after update to switch off the fact pane:

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/
IF EXISTS (SELECT * FROM sys.triggers WHERE OBJECT_ID = OBJECT_ID(N'utr_AZRCRV_UpdateSY07225SetFactBoxVisibleOff'))
	DROP TRIGGER utr_AZRCRV_UpdateSY07225SetFactBoxVisibleOff
GO

CREATE TRIGGER
	utr_AZRCRV_UpdateSY07225SetFactBoxVisibleOff ON SY07225
AFTER INSERT AS
	UPDATE
		['List View Options']
	SET
		FactBoxVisible = 0
	FROM
		SY07225 AS ['List View Options']
	INNER JOIN
		inserted
			ON
				inserted.ListDictID = ['List View Options'].ListDictID
			AND
				inserted.ListID = ['List View Options'].ListID
			AND
				inserted.ViewID = ['List View Options'].ViewID
			AND
				inserted.USERID = ['List View Options'].USERID
GO

The second script, is a run once script after the trigger is created; it sets all existing entries in the table to off so that existing users don’t see the fact pane:

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/
UPDATE SY07225 SET FactBoxVisible = 0
GO

SQL Script to Notify When Upgrade Complete

Microsoft Dynamics GPThis SQL script was written for a client with a large number of databases and which took a long time to update and they needed to upgrade through several versions of Microsoft Dynamics GP. The script checks for start and end times in the DB_UPGRADE table; when they match for all rows, an error is raised.

The script was scheduled using SQL Server Agent which was configured to send an email when the error was raised; this allowed him to know when part of the upgrade had completed and the next stage needed to be started.

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/
DECLARE @UpgradeComplete AS INT

SELECT
	@UpgradeComplete = CASE WHEN COUNT(PRODID) = 0 THEN 1 ELSE 0 END
FROM
	DB_UPGRADE
WHERE
	start_time = stop_time

IF (@UpgradeComplete = 1)
	/*
	throw error because all companies upgraded
	if <> 0, that means upgrade still running and nothing needs to occur
	*/
	RAISERROR ('GP 2016 upgrade complete; next stage needs to be started',11,1)

SQL Script to Change Compatibility of All Databases

Microsoft Dynamics GPWhen moving databases between servers for an upgrade of Microsoft Dynamics GP, you will, when also upgrading SQL Server, need to change the compatibility level of the databases. Rather than dong this individually, the below script can be run against the system database to generate a script you can then run to update the compatibility level of all databases.

The highlighted variable should be changed to the relevant version.

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/
DECLARE @CompatibilityLevel VARCHAR(140) = 140


SELECT 'USE master
	GO
	ALTER DATABASE [' + DB_NAME() + '] SET COMPATIBILITY_LEVEL = ' + @CompatibilityLevel + '
	GO'
UNION ALL
	SELECT '
		ALTER DATABASE [' + ['Company Master'].INTERID + '] SET COMPATIBILITY_LEVEL = ' + @CompatibilityLevel + '
		GO'
	FROM
		SY01500 AS ['Company Master']
GO

This script doesn’t get the logical file name, but I’ve hooked it into the series I did on Logical File Name SQL Scripts as it will often be needed at the same time.

Click to show/hide the Logical File Name SQL Scripts Series Index

SQL Script to Change Database Owner of All Databases

Microsoft Dynamics GPWhen moving databases between servers, you need to make sure the databases are set to have an owner of DYNSA. Rather than dong this individually, the below script can be run against the system database to generate a script you can then run to update the db owner.

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/
SELECT 'USE [' + DB_NAME() + ']
	GO
	sp_changedbowner ''DYNSA''
	GO'
UNION
	SELECT 'USE [' + ['Company Master'].INTERID + ']
		GO
		sp_changedbowner ''DYNSA''
		GO'
	FROM
		SY01500 AS ['Company Master']
GO

This script doesn’t get the logical file name, but I’ve hooked it into the series I did on Logical File Name SQL Scripts as it will often be needed at the same time.

Click to show/hide the Logical File Name SQL Scripts Series Index

POWERUSER Removed From ‘sa’; No Other User With Security Access

Microsoft Dynamics GPOne of the project managers was doing some testing for a development project recently and accidentally changed the security for the ‘sa’ account; they removed the ‘POWERUSER’ role (which gives global access to Microsoft Dynamics GP. In its place, they assigned the AP CLERK role.

What made this a major issue, was that the development system only had one company and this left the system with no users with access to the security windows.

They made the mistake by selecting the sa account instead of the sam account. Unfortunately, it was only after logging out as sa and back in as sam that they realised what they had done.

Fortunately, this isn’t actually too complext to fix, although it does require some SQL.

The sa account needed to be added back into the Security Assignment User Role (SY10500) table. I used a very simple script for fixing the development system, but have then tidied it up a little to post here.

This script adds POWERUSER back to the sa account for all companies and needs to be run against the system database (typically called DYNAMICS):

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/
INSERT INTO SY10500
	(USERID,CMPANYID,SECURITYROLEID)
--VALUES
	(
	SELECT
		'sa',CMPANYID,'POWERUSER'
	FROM
		SY01500 AS ['Company Master']
	WHERE
		(
		SELECT
			COUNT(*)
		FROM
			SY10500 AS ['Security Assignment User Role']
		WHERE
			['Security Assignment User Role'].CMPANYID = ['Company Master'].CMPANYID
		AND
			['Security Assignment User Role'].USERID = 'sa'
		) = 0
	)
GO

Before running, please make sure you are happy with what the script will do and have a good backup of your system database.

Update Taxes In Fabrikam Sample Company to Add Current UK VAT Rates

Microsoft Dynamics GPWhile the Fabrikam sample company is very US-centric, it is still somewhat useful to use as it has data spread across lots of different modules. The sample data hasn’t been updated for years and so still has the UK VAT rate set at 17.5%; VAT was raised to 20% in the 2010 budget and came into force in January 2011.

I created a script a while ago which could be used to create VAT rates for use in both Purchasing and Sales.

In Sales only a Standard 20% rate is created, but for purchasing rates are created for the Standard 20%, reduced 5%, Exempt and Zero Rated.

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 2.0 UK: England & Wales (CC BY-NC-SA 2.0 UK).
*/
-- Sales/Purchases Tax Schedule Header Master (TX00101)
INSERT INTO TX00101
	(TAXSCHID,TXSCHDSC,NOTEINDX)
VALUES
	-- Purchasing
	('UKVATP','UK VAT All Purchasing',0)
	,('UKVATPS','UK VAT Purchasing Standard',0)
	,('UKVATPR','UK VAT Purchasing Reduced',0)
	,('UKVATPE','UK VAT Purchasing Exempt',0)
	,('UKVATPZ','UK VAT Purchasing Zero',0)
	-- Sales
	,('UKVATS','UK VAT All Sales',0)
	,('UKVATSS','UK VAT Sales Standard',0)
GO

-- Sales/Purchases Tax Schedule Master (TX00102)
INSERT INTO TX00102
	(TAXSCHID,TAXDTLID,TXDTLBSE,TDTAXTAX,Auto_Calculate)
VALUES
	-- Purchasing
	('ALL DETAILS','UKVATPS',3,0,0)
	,('ALL DETAILS','UKVATPR',3,0,0)
	,('ALL DETAILS','UKVATPE',3,0,0)
	,('ALL DETAILS','UKVATPZ',3,0,0)
	,('UKVATP','UKVATPS',3,0,0)
	,('UKVATP','UKVATPR',3,0,0)
	,('UKVATP','UKVATPE',3,0,0)
	,('UKVATP','UKVATPZ',3,0,0)
	,('UKVATPS','UKVATPS',3,0,0)
	,('UKVATPR','UKVATPR',3,0,0)
	,('UKVATPE','UKVATPE',3,0,0)
	,('UKVATPZ','UKVATPZ',3,0,0)
	--Sales
	,('ALL DETAILS','UKVATSS',3,0,0)
	,('UKVATS','UKVATSS',3,0,0)
	,('UKVATSS','UKVATSS',3,0,0)
GO

--Sales/Purchases Tax Master (TX00201)
INSERT INTO TX00201
	(TAXDTLID,TXDTLDSC,TXDTLTYP,ACTINDX,TXIDNMBR,TXDTLBSE,TXDTLPCT,TXDTLAMT,TDTLRNDG,TXDBODTL,TDTABMIN,TDTABMAX,TDTAXMIN,TDTAXMAX,TDRNGTYP,TXDTQUAL,TDTAXTAX,TXDTLPDC,TXDTLPCH,TXDXDISC,CMNYTXID,NOTEINDX,NAME,CNTCPRSN,ADDRESS1,ADDRESS2,ADDRESS3,CITY,STATE,ZIPCODE,COUNTRY,PHONE1,PHONE2,PHONE3,FAX,TXUSRDF1,TXUSRDF2,VATREGTX,TaxInvReqd,TaxPostToAcct,TaxBoxes,IGNRGRSSAMNT,TDTABPCT)
VALUES
	-- Purchasing
	('UKVATPS','UK VAT Purchasing Standard',2,90,'',3,20.00000,0,1,'',0,0,0,0,1,1,0,0,'',0,'',0,'','','','','','','','','','','','','','','',0,0,1,0x00000000,0,0)
	,('UKVATPR','UK VAT Purchasing Reduced',2,90,'',3,5.00000,0,1,'',0,0,0,0,1,1,0,0,'',0,'',0,'','','','','','','','','','','','','','','',0,0,1,0x00000000,0,0)
	,('UKVATPE','UK VAT Purchasing Exempt',2,90,'',3,0.00000,0,1,'',0,0,0,0,1,1,0,0,'',0,'',0,'','','','','','','','','','','','','','','',0,0,1,0x00000000,0,0)
	,('UKVATPZ','UK VAT Purchasing Zero',2,90,'',3,0.00000,0,1,'',0,0,0,0,1,1,0,0,'',0,'',0,'','','','','','','','','','','','','','','',0,0,1,0x00000000,0,0)
	-- Sales
	,('UKVATSS','UK VAT Sales Standard',1,89,'',3,20.00000,0,1,'',0,0,0,0,1,1,0,0,'',0,'',0,'','','','','','','','','','','','','','','',0,0,1,0x00000000,0,0)
GO

--Sales/Purchases Tax Summary Master (TX00202)
INSERT INTO TX00202
	(TAXDTLID,TDTSYTD,TDSLLYTD,TXDTSYTD,TDTSLYTD,TXDSTYTD,TDSTLYTD,KPCALHST,KPERHIST)
VALUES
	-- Purchases
	('UKVATPS',0,0,0,0,0,0,1,1)
	,('UKVATPR',0,0,0,0,0,0,1,1)
	,('UKVATPE',0,0,0,0,0,0,1,1)
	,('UKVATPZ',0,0,0,0,0,0,1,1)
	-- Sales
	,('UKVATSS',0,0,0,0,0,0,1,1)
GO

This script has only ever been tested in the Fabrikam sample company; the script will need to be run again any time you redeploy the sample company using GP Utilities.

SQL Script to Alter Server and Database Views After Copying Live To Test

Microsoft Dynamics GPMicrosoft Dynamics GP includes a number of views in the database which are used to drive some of the reporting (such as the Refreshable Excel Reports); these reports contain drill down links. I’ve never really done that much work with the views myself, but I was alerted to an issue by a partner organisation who was creating some reports from Dynamics GP integrated with data from their system.

As development was in progress, the partner was working on the clients standalone test system, but when they tested the drill downs, the data was coming from the live system. I did some exploring of the views and found that the drilldowns are coded during deployment to include the server and database:

'Account Index For Drillback' = 'dgpp://DGPB/?Db=GP&Srv=2018SQL1\GP&Cmp=TEST&Prod=0' +dbo.dgppAccountIndex(1,['Account Master'].[ACTINDX] )

This issue will affect the views not only when the databases are copied to a new system, but also when a live company is copied to a test company on the same server.

The solution was to create a script which would alter the views to the new server or database:

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/

DECLARE @ViewDefinition AS NVARCHAR(max)

DECLARE @OldDatabase AS VARCHAR(5) = 'TWO'
DECLARE @NewDatabase AS VARCHAR(5) = DB_NAME()

DECLARE @OldServer AS VARCHAR(50) = '2018SQL1'
DECLARE @NewServer AS VARCHAR(50) = @@ServerName

CREATE TABLE #ViewDefinitions(
	ViewDefinition NVARCHAR(MAX)
	,ROW_ID INT IDENTITY
)

INSERT INTO #ViewDefinitions
	(ViewDefinition)
--VALUES
	(SELECT
		REPLACE(
			REPLACE(['SQL Modules'].definition, 'CREATE VIEW', 'ALTER VIEW')
		,'Srv=' + @OldServer + '&Cmp=' + @OldDatabase,'Srv=' + @NewServer + '&Cmp=' + @NewDatabase)
	FROM
		sys.all_views AS ['All Views']
	JOIN
		sys.sql_modules AS ['SQL Modules']
			ON
				['SQL Modules'].object_id = ['All Views'].object_id
	and
		['SQL Modules'].definition LIKE '%Srv=' + @OldServer + '&Cmp=' + @OldDatabase + '%')

DECLARE
	cursor_Views Cursor
FOR
	SELECT
		ViewDefinition
	FROM
		#ViewDefinitions
	
	Open cursor_Views

	FETCH NEXT FROM
		cursor_Views
	INTO
		@ViewDefinition
	WHILE (@@FETCH_STATUS <> -1)
		BEGIN
		IF (@@FETCH_STATUS <> -2)
			EXEC (@ViewDefinition)
			FETCH NEXT FROM
				cursor_Views
			INTO
				@ViewDefinition
		END
	CLOSE cursor_Views
DEALLOCATE cursor_Views

DROP TABLE #ViewDefinitions
GO

The script uses the @@ServerName and DB_Name functions for the new server and database names; the two highlighted sections are the parameters for the old server and database which need to be amended.

As this script updates the views, make sure you have a good database backup before running.

Updated 24/10/2018 following feedback fromDavid Morinello

Logical File Name SQL Scripts: SQL Script to Create Restore Scripts for all Dynamics Databases

Microsoft SQL ServerSince the release of Microsoft Dynamics GP 2018, on the 1st December 2018, we have been busy with a few upgrade projects for clients. Our standard recommendation is to have a standalone test system for performing UAT and this means backing up and restoring databases.

While the backups are easy to do, the restores can be trickier when one database has been restored into another, as this means the logical file name will not match the physical one.

This isn’t an issue when the client has only a handful of databases, but when there are 30 or even a hundred, it becomes much more of an issue. However, you can select database details in SQL Server from the sys.master_files single, system-wide view.

This script creates restore scripts for all Dynamics GP databases and will use the correct logical filename whether it matches the . The script is configured with the assumption that the system database is called DYNAMICS; if you are using a named system database, change the highlighted section:

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/
USE DYNAMICS
GO

DECLARE @BackupLocation VARCHAR(300) = 'I:\Live Upgrade\2016R2\'
DECLARE @DataLocation VARCHAR(300) = 'S:\Data\'
DECLARE @LogLocation VARCHAR(300) = 'L:\Logs\'
DECLARE @DateParameter VARCHAR(10) = FORMAT(GETDATE(), 'yyyy-MM-dd')
DECLARE @SQLStatement NVARCHAR(MAX)
SELECT @SQLStatement =	'
	USE master
	GO
	RESTORE DATABASE ' + DB_NAME() + ' FROM  
	DISK = N''' + @BackupLocation + DB_NAME() + '_' + @DateParameter + '.bak'' WITH  FILE = 1,  
	MOVE N''' + ['databases-data'].name + ''' TO N''' + @DataLocation + RIGHT(['databases-data'].physical_name, CHARINDEX('\', REVERSE(['databases-data'].physical_name)) - 1) + ''',  
	MOVE N''' + ['databases-log'].name + ''' TO N''' + @LogLocation + RIGHT(['databases-log'].physical_name, CHARINDEX('\', REVERSE(['databases-log'].physical_name)) - 1) + ''',  NOUNLOAD,  STATS = 5
	GO
	'
FROM
	sys.master_files AS ['databases-data']
INNER JOIN
	sys.master_files AS ['databases-log']
		ON
			DB_NAME(['databases-log'].database_id) = DB_NAME(['databases-data'].database_id)
WHERE
	DB_NAME(['databases-data'].database_id) = DB_NAME() and ['databases-data'].name like '%.mdf'

SELECT @SQLStatement = @SQLStatement + 
	'RESTORE DATABASE ' + RTRIM(['Company Master'].INTERID) + ' FROM  
	DISK = N''' + @BackupLocation + RTRIM(['Company Master'].INTERID) + '_' + @DateParameter + '.bak'' WITH  FILE = 1,  
	MOVE N''' + ['databases-data'].name + ''' TO N''' + @DataLocation + RIGHT(['databases-data'].physical_name, CHARINDEX('\', REVERSE(['databases-data'].physical_name)) - 1) + ''',  
	MOVE N''' + ['databases-log'].name + ''' TO N''' + @LogLocation + RIGHT(['databases-log'].physical_name, CHARINDEX('\', REVERSE(['databases-log'].physical_name)) - 1) + ''',  NOUNLOAD,  STATS = 5
	GO
	'
FROM
	SY01500 AS ['Company Master']
INNER JOIN
	sys.master_files AS ['databases-data']
		ON
			DB_NAME(['databases-data'].database_id) = ['Company Master'].INTERID AND ['databases-data'].name LIKE '%mdf'
INNER JOIN
	sys.master_files AS ['databases-log']
		ON
			DB_NAME(['databases-log'].database_id) = ['Company Master'].INTERID AND ['databases-log'].name LIKE '%ldf'
WHERE
	['databases-data'].name NOT LIKE '%<TEST>'
AND
	['Company Master'].CMPANYID > 0
ORDER BY
	['Company Master'].INTERID
	,['databases-data'].name

SELECT @SQLStatement

Click to show/hide the Logical File Name SQL Scripts Series Index

Logical File Name SQL Scripts: SQL Script to Create Backup Scripts for all Dynamics Databases

Microsoft SQL ServerSince the release of Microsoft Dynamics GP 2018, on the 1st December 2018, we have been busy with a few upgrade projects for clients. Our standard recommendation is to have a standalone test system for performing UAT and this means backing up and restoring databases.

While the backups are easy to do, the restores can be trickier when one database has been restored into another, as this means the logical file name will not match the physical one.

This isn’t an issue when the client has only a handful of databases, but when there are 30 or even a hundred, it becomes much more of an issue. However, you can select database details in SQL Server from the sys.master_files single, system-wide view.

This script creates backup scripts for all Dynamics GP databases. The script is configured with the assumption that the system database is called DYNAMICS; if you are using a named system database, change the highlighted section:

/*
Created by Ian Grieve of azurecurve|Ramblings of a Dynamics GP Consultant (http://www.azurecurve.co.uk)
This code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0 Int).
*/
USE DYNAMICS
GO

DECLARE @BackupLocation VARCHAR(300) = 'I:\Live Upgrade\2016R2\'
DECLARE @DateParameter VARCHAR(10) = FORMAT(GETDATE(), 'yyyy-MM-dd')
DECLARE @SQLStatement NVARCHAR(MAX) =	'
	USE master
	GO
	BACKUP DATABASE ' + DB_NAME() + ' TO
	DISK = N''' + @BackupLocation + DB_NAME() + '_' + @DateParameter + '.bak'' WITH NOFORMAT, INIT,    
	NAME = N''' + DB_NAME() + '-Full Database Backup'', SKIP, NOREWIND, NOUNLOAD,  STATS = 10
	GO
	'

SELECT @SQLStatement = @SQLStatement +
	'BACKUP DATABASE ' + RTRIM(['Company Master'].INTERID) + ' TO
	DISK = N''' + @BackupLocation + RTRIM(['Company Master'].INTERID) + '_' + @DateParameter + '.bak'' WITH NOFORMAT, INIT,    
	NAME = N''' + RTRIM(['Company Master'].INTERID) + '-Full Database Backup'', SKIP, NOREWIND, NOUNLOAD,  STATS = 10
	GO
	'
FROM
	SY01500 AS ['Company Master']
INNER JOIN
	sys.master_files ['databases-data']
		ON
			DB_NAME(['databases-data'].database_id) = ['Company Master'].INTERID AND ['databases-data'].name LIKE '%mdf'
WHERE
	['databases-data'].name NOT LIKE '%<TEST>'
AND
	['Company Master'].CMPANYID > 0
ORDER BY
	['Company Master'].INTERID
	,['databases-data'].name

SELECT @SQLStatement

Click to show/hide the Logical File Name SQL Scripts Series Index