Task: to create a fully automatic database backup system by means of SQL Server Agent Job with an e-mail fails notification subsystem



EXEC [master].[dbo].[sp_addumpdevice]
     @devtype      = N'disk',
     @logicalname  = N'AdventureWorks2008R2',
     @physicalname = N'D:\SqlData\MSSQL\Backup\AdventureWorks2008R2.bak'
GO

Source code 1: SSMS -> Object Explorer -> [sql_server_instance] -> Server Objects -> Backup Devices -> AdventureWorks2008R2



EXEC [master].[dbo].[sp_configure] 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC [master].[dbo].[sp_configure] 'xp_cmdshell', 1
GO
RECONFIGURE
GO

USE [master]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[Backup]
AS
BEGIN
    DECLARE @Out INT

    -- NOTE: make sure the database is in Full Recovery Model and is online!
    ALTER DATABASE [AdventureWorks2008R2]
    SET RECOVERY FULL
    ALTER DATABASE [AdventureWorks2008R2]
    SET ONLINE
    -- NOTE: functional for a FileStream database as well!

    DBCC CHECKDB([AdventureWorks2008R2])

    -- Create a database backup
    EXEC @Out = [master]..[xp_cmdshell]
                N'D:\SqlData\MSSQL\Backup\BACKUP_FILO_BEGIN.bat'

    CHECKPOINT

    BACKUP LOG [AdventureWorks2008R2]
               TO DISK='NUL' --WITH TRUNCATE_ONLY
    BACKUP DATABASE [AdventureWorks2008R2]
                    TO [AdventureWorks2008R2] WITH COMPRESSION --WITH INIT

    -- Copy the backup database to a tape
    EXEC @Out = [master]..[xp_cmdshell]
                N'D:\SqlData\MSSQL\Backup\BACKUP_FILO_END.bat'
END
GO

Source code 2: SSMS -> Object Explorer -> [sql_server_instance] -> Databases -> System Databases -> master -> Programmability -> Stored Procedures -> dbo.Backup



REM ***Creating a Database Backup***

REM Path: "D:\SqlData\MSSQL\Backup\"
SET FILEPATH="D:\SqlData\MSSQL\Backup\"

SET FILENAME="AdventureWorks2008R2"

IF EXIST %FILEPATH%\%FILENAME%.BA4 DEL    %FILEPATH%\%FILENAME%.BA4
IF EXIST %FILEPATH%\%FILENAME%.BA3 RENAME %FILEPATH%\%FILENAME%.BA3 %FILENAME%.BA4
IF EXIST %FILEPATH%\%FILENAME%.BA2 RENAME %FILEPATH%\%FILENAME%.BA2 %FILENAME%.BA3
IF EXIST %FILEPATH%\%FILENAME%.BA1 RENAME %FILEPATH%\%FILENAME%.BA1 %FILENAME%.BA2
IF EXIST %FILEPATH%\%FILENAME%.BAK COPY   %FILEPATH%\%FILENAME%.BAK %FILEPATH%\%FILENAME%.BA1

SET FILENAME=
SET FILEPATH=

Source code 3: Creating a database backup – BACKUP_FILO_BEGIN.bat



REM ***Copying the Database Backup to a Tape***

REM Path: "D:\SqlData\MSSQL\Backup\"
SET FILEPATHSRC="D:\SqlData\MSSQL\Backup\"

REM Path: "\\[server_name]\SQL_BAK$"
SET FILEPATHDST="\\[server_name]\SQL_BAK$"

SET FILENAME="AdventureWorks2008R2"

COPY %FILEPATHSRC%\%FILENAME%.BAK %FILEPATHDST%\%FILENAME%.BAK

SET FILENAME=
SET FILEPATHSRC=
SET FILEPATHDST=

Source code 4: Copying the database backup to a tape – BACKUP_FILO_END.bat



USE [msdb]
GO

EXEC [msdb].[dbo].[sp_add_operator]
     @name                      = N'BACKUP',
     @enabled                   = 1,
     @weekday_pager_start_time  = 90000,
     @weekday_pager_end_time    = 180000,
     @saturday_pager_start_time = 90000,
     @saturday_pager_end_time   = 180000,
     @sunday_pager_start_time   = 90000,
     @sunday_pager_end_time     = 180000,
     @pager_days                = 0,
     @email_address             = N'test@example.eu',
     @category_name             = N'[Uncategorized]'
GO

Source code 5: SSMS -> Object Explorer -> [sql_server_instance] -> SQL Server Agent -> Operators -> BACKUP



USE [msdb]
GO

BEGIN TRANSACTION
    DECLARE @ReturnCode INT
    SELECT  @ReturnCode = 0

    IF NOT EXISTS
    (
        SELECT [name]
        FROM   [msdb].[dbo].[syscategories]
        WHERE  [name]           = N'Database Maintenance'
               AND
               [category_class] = 1 -- Job
    )
    BEGIN
        EXEC @ReturnCode = [msdb].[dbo].[sp_add_category]
                           @class = N'JOB',
                           @type  = N'LOCAL',
                           @name  = N'Database Maintenance'
        IF (@@ERROR != 0 OR @ReturnCode != 0)
        BEGIN
            GOTO QuitWithRollback
        END
    END

    DECLARE @jobId BINARY(16)
    EXEC @ReturnCode = [msdb].[dbo].[sp_add_job]
		       @job_name                   = N'BACKUP',
		       @enabled                    = 1,
		       @notify_level_eventlog      = 2,
		       @notify_level_email         = 2,
		       @notify_level_netsend       = 0,
		       @notify_level_page          = 0,
		       @delete_level               = 0,
		       @description                = N'Creating a database backup by means of SQL Server Agent Job',
		       @category_name              = N'Database Maintenance',
		       @owner_login_name           = N'NB0046\Marian Placko',
                       @notify_email_operator_name = N'BACKUP',
                       @job_id                     = @jobId OUTPUT
    IF (@@ERROR != 0 OR @ReturnCode != 0)
    BEGIN
        GOTO QuitWithRollback
    END
    EXEC @ReturnCode = [msdb].[dbo].[sp_add_jobstep]
		       @job_id               = @jobId,
		       @step_name            = N'BACKUP',
		       @step_id              = 1,
		       @cmdexec_success_code = 0,
		       @on_success_action    = 1,
		       @on_success_step_id   = 0,
		       @on_fail_action       = 2,
		       @on_fail_step_id      = 0,
		       @retry_attempts       = 0,
		       @retry_interval       = 0,
		       @os_run_priority      = 0,
		       @subsystem            = N'TSQL',
		       @command              = N'EXEC [dbo].[Backup]',
		       @database_name        = N'master',
		       @flags                = 0
    IF (@@ERROR != 0 OR @ReturnCode != 0)
    BEGIN
        GOTO QuitWithRollback
    END
    EXEC @ReturnCode = [msdb].[dbo].[sp_update_job]
                       @job_id        = @jobId,
                       @start_step_id = 1
    IF (@@ERROR != 0 OR @ReturnCode != 0)
    BEGIN
        GOTO QuitWithRollback
    END
    DECLARE @guid UNIQUEIDENTIFIER
    SET     @guid = NEWID()
    EXEC @ReturnCode = [msdb].[dbo].[sp_add_jobschedule]
		       @job_id                 = @jobId,
		       @name                   = N'BACKUP',
		       @enabled                = 1,
		       @freq_type              = 8,
		       @freq_interval          = 62,
		       @freq_subday_type       = 1,
		       @freq_subday_interval   = 0,
		       @freq_relative_interval = 0,
		       @freq_recurrence_factor = 1,
		       @active_start_date      = 20111230,
		       @active_end_date        = 99991231,
		       @active_start_time      = 200000,
		       @active_end_time        = 235959,
		       @schedule_uid           = @guid
    IF (@@ERROR != 0 OR @ReturnCode != 0)
    BEGIN
        GOTO QuitWithRollback
    END
    EXEC @ReturnCode = [msdb].[dbo].[sp_add_jobserver]
                       @job_id      = @jobId,
                       @server_name = N'(local)'
    IF (@@ERROR != 0 OR @ReturnCode != 0)
    BEGIN
        GOTO QuitWithRollback
    END
COMMIT TRANSACTION
    GOTO EndSave
QuitWithRollback:
    IF (@@TRANCOUNT > 0)
    BEGIN
        ROLLBACK TRANSACTION
    END
EndSave:
GO

Source code 6: SSMS -> Object Explorer -> [sql_server_instance] -> SQL Server Agent -> Jobs -> BACKUP



-- Enable a Database Mail
[master].[dbo].[sp_configure] 'show advanced options', 1
GO
RECONFIGURE
GO
[master].[dbo].[sp_configure] 'Database Mail XPs', 1
GO
RECONFIGURE
GO

-- Set up an Account
 -- Port number: 25
 -- SMPT authentication: anonymous
EXECUTE [msdb].[dbo].[sysmail_add_account_sp]
        @account_name    = 'BACKUP',
        @description     = 'Creating a database backup by means of SQL Server Agent Job',
        @email_address   = 'test@example.eu',
        @display_name    = 'BACKUP',
        @replyto_address = 'test@example.eu',
        @mailserver_name = 'localhost' -- NOTE: SMTP server must be set up!
GO

-- Set up a Profile
EXECUTE [msdb].[dbo].[sysmail_add_profile_sp]
        @profile_name = 'BACKUP',
        @description  = 'Creating a database backup by means of SQL Server Agent Job'
GO

-- Associate the Profile with the Account
EXECUTE [msdb].[dbo].[sysmail_add_profileaccount_sp]
        @profile_name    = 'BACKUP',
        @account_name    = 'BACKUP',
        @sequence_number = 1
GO

-- Add NB0046\Marian Placko to the Database Mail Role
EXEC [msdb].[dbo].[sp_addrolemember]
     @rolename   = 'DatabaseMailUserRole',
     @membername = 'NB0046\Marian Placko'
GO

-- Grant access to the Profile to NB0046\Marian Placko
EXEC [msdb].[dbo].[sysmail_add_principalprofile_sp]
     @profile_name   = 'BACKUP',
     @principal_name = 'NB0046\Marian Placko',
     @is_default     = 0
GO

-- Send a test e-mail
EXEC [msdb].[dbo].[sp_send_dbmail]
     @profile_name='BACKUP',
     @recipients='test@example.eu',
     @subject='Test message',
     @body='This is the body of the test message.'

Source code 7: SSMS -> Object Explorer -> [sql_server_instance] -> Management -> Database Mail -> BACKUP



-- Enable SQL Server Agent to use the Database Mail
 -- NOTE: make sure to start SQL Server Agent!
 EXEC master.dbo.xp_ServiceControl 'QUERYSTATE','SQLServerAgent'
 -- Current Service State: Running.
 --EXEC master.dbo.xp_ServiceControl 'START', 'SQLServerAgent'
 GO

EXEC [msdb].[dbo].[sp_set_sqlagent_properties]
     @email_save_in_sent_folder = 1

EXEC [master].[dbo].[xp_instance_regwrite]
     N'HKEY_LOCAL_MACHINE',
     N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
     N'UseDatabaseMail',
     N'REG_DWORD',
     1

EXEC [master].[dbo].[xp_instance_regwrite]
     N'HKEY_LOCAL_MACHINE',
     N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
     N'DatabaseMailProfile',
     N'REG_SZ',
     N'BACKUP'
GO

-- Enable SQL Server Agent to set Fail-safe Operator
EXEC [master].[dbo].[sp_MSsetalertinfo]
     @failsafeoperator   = N'BACKUP',
     @notificationmethod = 1 -- E-mail
GO
 -- NOTE: make sure to restart SQL Server Agent!
 EXEC master.dbo.xp_ServiceControl 'STOP', 'SQLServerAgent'
 GO
 -- Message: Service Stopped.
 EXEC master.dbo.xp_ServiceControl 'START', 'SQLServerAgent'
 GO
 -- Message: Service Started.

Source code 8: SSMS -> Object Explorer -> [sql_server_instance] -> SQL Server Agent -> Properties -> Alert System


Additional references:

The SQL professionals know that the built-in MS SQL Server encryption mechanism by means of WITH ENCRYPTION T-SQL keyword is ineffective and easily broken. For much more details see also Google’s results e.g.:

{3S} SQL Smart Security is an add-in which can be installed in Microsoft SQL Server Management Studio (SSMS) 2005, 2008, 2008 R2 and their respective Express versions. It enables software companies to create a secured content for database objects (note: currently, in 1.0 version can be secured only the content of stored procedures, but in the future, there are considered user defined functions, triggers and views as well). It brings much higher level of protection in comparison with SQL Server built in WITH ENCRYPTION mechanism for software companies that want to protect their heavily acquired know-how by creation of application logic on the database server side on a daily basis.

None of the currently available SQL decryptors are capable of cracking {3S} SQL Smart Security. Most importantly, all encrypted database objects remain executable! Moreover, installing {3S} SQL Smart Security does not affect any settings and does not replace default encryption options entirely. The developers (end-users) always have an option to choose which encryption settings to use.

See a short story of a simple hack by means of built-in MS SQL Server WITH ENCRYPTION mechanism on the example bellow.

WARNING: In the following examples, an excellent free tool called dbForge SQL Decryptor by the Devart (formerly known as Core Lab) software development company (http://www.devart.com/) will be used for educational purposes, only for decrypting the stored procedure.

built-in WITH ENCRYPTION hack – stored procedure encryption by means of built-in MS SQL Server WITH ENCRYPTION mechanism

Figure 1: built-in WITH ENCRYPTION hack – stored procedure encryption by means of built-in MS SQL Server WITH ENCRYPTION mechanism


built-in WITH ENCRYPTION hack – lock on encrypted stored procedure by means of built-in MS SQL Server WITH ENCRYPTION mechanism

Figure 2: built-in WITH ENCRYPTION hack – lock on encrypted stored procedure by means of built-in MS SQL Server WITH ENCRYPTION mechanism


built-in WITH ENCRYPTION hack – stored procedure decrypting by means of dbForge SQL Decryptor

Figure 3: built-in WITH ENCRYPTION hack – stored procedure decrypting by means of dbForge SQL Decryptor


built-in WITH ENCRYPTION hack – decrypted stored procedure by means of dbForge SQL Decryptor

Figure 4: built-in WITH ENCRYPTION hack – decrypted stored procedure by means of dbForge SQL Decryptor

By applying dbForge SQL Decryptor to the encrypted stored procedure by means of built-in MS SQL Server WITH ENCRYPTION mechanism it is possible to see that the stored procedure body IS A PLAIN SOURCE CODE TEXT!!!

built-in WITH ENCRYPTION hack – encrypted stored procedure by means of {3S} SQL Smart Security

Figure 5: built-in WITH ENCRYPTION hack – encrypted stored procedure by means of {3S} SQL Smart Security


built-in WITH ENCRYPTION hack – decrypted {3S} SQL Smart Security stored procedure by means of dbForge SQL Decryptor

Figure 6: built-in WITH ENCRYPTION hack – decrypted {3S} SQL Smart Security stored procedure by means of dbForge SQL Decryptor

By applying dbForge SQL Decryptor to the encrypted stored procedure by means of {3S} SQL Smart Security it is possible to see that the stored procedure body IS NOT A PLAIN SOURCE CODE TEXT but includes the {3S} SQL Smart Security metadata only!!!

Additional references:


{3S} SQL Smart Security ''Protect your T-SQL know-how!''

Task: to create row values concatenation, i.e. CSV (Comma Separated Values), by means of the FOR XML PATH construction, and to export database table column values to the MS Excel file using the Microsoft.Jet.OLEDB ad hoc method of connecting and accessing remote data by using OLE DB
Solution: see Source code 1 – 4



EXEC sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
EXEC sp_configure 'ad hoc distributed queries', 1;
GO
RECONFIGURE;
GO

Source code 1: system configuration



USE [AdventureWorks]
GO

DECLARE @InputData        AS TABLE
(
        [ManagerCounter]  INT,
        [ManagerLoginID]  NVARCHAR(256),
        [EmployeeLoginID] NVARCHAR(256)
)
;WITH [Employees]
(
      [ManagerCounter],
      [ManagerID],
      [LoginID]
)
AS
(
    SELECT ROW_NUMBER() OVER(PARTITION BY [ManagerID] ORDER BY [ManagerID]),
           [ManagerID],
           [LoginID]
    FROM   [HumanResources].[Employee]
)
INSERT INTO @InputData
(
            [ManagerCounter],
            [ManagerLoginID],
            [EmployeeLoginID]
)
SELECT   [ManagerCounter],
         [Managers].[LoginID],
         [Employees].[LoginID]
FROM     [HumanResources].[Employee] AS [Managers] INNER JOIN [Employees] ON
         [Managers].[EmployeeID] = [Employees].[ManagerID]
ORDER BY [Managers].[LoginID]

/* temporary test */
SELECT    [ManagerCounter]  AS 'ManagersCounter',
          [ManagerLoginID]  AS 'Managers',
          [EmployeeLoginID] AS 'Employees'
FROM      @InputData
ORDER BY  [ManagerLoginID]

Source code 2: input data preparation (ManagersCounter – number of employees per manager)


MS SSMS result of input data preparation (ManagersCounter - number of employees per manager)

Figure 1: MS SSMS result of input data preparation (ManagersCounter - number of employees per manager)



SELECT       [Managers].[ManagerLoginID] AS 'Manager',
(
    SELECT
        CASE
	     WHEN [Employees].[ManagerCounter] = 1
                  THEN [Employees].[EmployeeLoginID]
	     ELSE ',' + [Employees].[EmployeeLoginID]
	END
    FROM     @InputData AS [Employees]
    WHERE    [Employees].[ManagerLoginID] = [Managers].[ManagerLoginID]
    ORDER BY [Employees].[ManagerLoginID]
    FOR XML  PATH('')
)            AS 'Employees'
FROM         @InputData AS [Managers]
GROUP BY     [Managers].[ManagerLoginID]

Source code 3: row values concatenation (converting to the CSV format) by means of FOR XML PATH


MS SSMS result of row values concatenation (converting to the CSV format) by means of FOR XML PATH

Figure 2: MS SSMS result of row values concatenation (converting to the CSV format) by means of FOR XML PATH



INSERT INTO OPENROWSET
(
            'Microsoft.Jet.OLEDB.4.0',
            'Excel 8.0;Database=C:\Managers.xls;',
                -- NOTE: the MS Excel file must already exist on the disk
                --       together with the specified path and name!
            'SELECT [Managers] FROM [Managers$]'
                -- NOTE: the above-mentioned MS Excel file must have one
                --       sheet named Managers, and the value in cell [0, 0],
                --       i.e. the first row and column, must be
                --       set to Managers (see Figure 5)!
)
SELECT	    [Managers].[ManagerLoginID]
FROM	    @InputData AS [Managers]
GROUP BY    [Managers].[ManagerLoginID]

GO

Source code 4: exporting data (the column Managers) to the MS Excel file on the disk


MS SSMS result of exported data (the column Managers) to the MS Excel file on the disk - error

Figure 3: MS SSMS result of exported data (the column Managers) to the MS Excel file on the disk - error


MS SSMS result of exported data (the column Managers) to the MS Excel file on the disk - solution for the above error

Figure 4: MS SSMS result of exported data (the column Managers) to the MS Excel file on the disk - solution for the above error


MS SSMS result of exported data (the column Managers) to the MS Excel file on the disk

Figure 5: MS SSMS result of exported data (the column Managers) to the MS Excel file on the disk


Additional references:
Task: to determine the behaviour of particular transaction isolation levels with respect to concurrent SQL query …SELECT TOP(1) [...] + 1…
Solution: see Figure 2


USE [Test_IsolationLevels]
GO
Source code 1: Use database

CREATE TABLE [dbo].[IsoSelTopOnePlusOne](
 [Identity] [int] IDENTITY(1,1) NOT NULL,
 [TopOnePlusOne] [int] NOT NULL,
 [ModifiedDate] [datetime] NOT NULL
) ON [PRIMARY]
GO
Source code 2: Create table

-- 0: (NOTE: default isolation level)
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
---- 1:
--SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
---- 2:
--SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
---- 3:
--SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
---- 4:
--ALTER DATABASE [Test_IsolationLevels] SET ALLOW_SNAPSHOT_ISOLATION ON
--SET TRANSACTION ISOLATION LEVEL SNAPSHOT
---- 5: (NOTE: set up failed)
--ALTER DATABASE [Test_IsolationLevels] SET READ_COMMITTED_SNAPSHOT ON
GO

DBCC USEROPTIONS
GO
Source code 3: Set up and select user options

DBCC USEROPTIONS

Figure 1: SSMS result of DBCC USEROPTIONS

CREATE PROCEDURE [dbo].[IsoSelTopOnePlusOne_Ins]
AS
BEGIN
 -- 0: (NOTE: default isolation level)
 SET TRANSACTION ISOLATION LEVEL READ COMMITTED
 ---- 1:
 --SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
 ---- 2:
 --SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
 ---- 3:
 --SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
 ---- 4:
 --SET TRANSACTION ISOLATION LEVEL SNAPSHOT

 BEGIN TRANSACTION IsoSelTop1PlusOne 

  DECLARE @Top1PlusOne INT
  SET @Top1PlusOne =
  (
   SELECT TOP(1) [TopOnePlusOne] + 1
   FROM [dbo].[IsoSelTopOnePlusOne]
   ORDER BY [TopOnePlusOne] DESC
  )
  IF
  (
   @Top1PlusOne
  ) IS NULL
  BEGIN
   SET @Top1PlusOne = 0
  END

  INSERT INTO [dbo].[IsoSelTopOnePlusOne]
  (
   [TopOnePlusOne],
   [ModifiedDate]
  )
  VALUES
  (
   @Top1PlusOne,
   GETDATE()
  )

  WAITFOR DELAY '00:00:10'

 COMMIT TRANSACTION IsoSelTop1PlusOne
END
GO
Source code 4: Create procedure

EXEC [dbo].[IsoSelTopOnePlusOne_Ins]
GO
Source code 5: Execute procedure

SELECT TABLE [dbo].[IsoSelTopOnePlusOne]

Figure 2: SSMS result of concurrent behaviour at the transaction isolation levels


Measuring results:

[Identity] Isolation Level [TopOnePlusOne] match/mismatch
1-2 ISOLATION LEVEL READ COMMITTED 0, 1 mismatch
3-4 ISOLATION LEVEL READ UNCOMMITTED 2, 3 mismatch
5-6 ISOLATION LEVEL REPEATABLE READ 4, 5 mismatch
7-8 ISOLATION LEVEL SERIALIZABLE 6, 7 mismatch
9-10 ISOLATION LEVEL SNAPSHOT 8, 8 match

The measurement above included 2 concurrent SQL queries (two SSMS windows). The second query started up approximately in half of the first SQL query.

Additional references:

Other references:

Parsing T-SQL

Posted: December 15, 2010 in MSSQL
Tags:

Task: syntax parsing and checking db object existence in SQL query
Solution: see Source code No. 4


Source code No. 1: Syntax parsing of SQL

DECLARE @SqlQuery NVARCHAR(4000)
SET @SqlQuery = 'SELECT [ID] FRON [dbo].[Parsing_T-SQL]'
EXEC ('SET FMTONLY ON ' + @SqlQuery)

Figure 1: SSMS SQL query result – syntax parsing of SQL
Figure 1: SSMS SQL query result - syntax parsing of SQL

Source code No. 2: Table existence check

DECLARE @SqlQuery NVARCHAR(4000)
SET @SqlQuery = 'SELECT [ID] FROM [dbo].[Parsing_T-SQL]'
EXEC ('SET FMTONLY ON ' + @SqlQuery)

Figure 2: SSMS SQL query result – table existence check
Figure 2: SSMS SQL query result - table existence check

Notes:

  • syntax parsing and checking db object existence in SQL query is valid equally for all commands of DML set (it means: SELECT/INSERT/UPDATE/DELETE)
  • functionally identical for EXEC and EXEC sp_executesql
  • option SET NOEXEC ON and SET PARSEONLY ON executed syntax parsing only but not db object existence check (db object existence check may be carried out by means of SYSOBJECTS, SYSCOLUMNS etc.)
  • the structure of BEGIN TRAN-ROLLBACK TRAN is not suitable because not all operations may be rollbacked (e.g. DROP DATABASE)

Source code No. 3: Syntax parsing and checking the existence in SQL query with user’s parameter (i.e. input)

DECLARE @SqlQuery NVARCHAR(4000)
SET @SqlQuery = 'UPDATE [dbo].[Parsing_T-SQL] SET [Value] = ''Test'' WHERE [ID] = @ID'
EXEC ('SET FMTONLY ON ' + @SqlQuery)

Figure 3: SSMS SQL query result – syntax parsing and checking the existence in SQL query with user’s parameter (input)
Figure 3: SSMS SQL query result - syntax parsing and checking the existence in SQL query with user's parameter (input)

Note: PARSE is OK but for EXECUTE see Figure 3

Solution: replacement @ID = 1 (see Source code No. 4)

Source code No. 4: Syntax parsing and checking the existence in SQL query with user’s parameter (i.e. input) and replacement @ID = 1

DECLARE @SqlQuery NVARCHAR(4000)
SET @SqlQuery = 'UPDATE [dbo].[Parsing_T-SQL] SET [Value] = ''Test'' WHERE [ID] = 1'
EXEC ('SET FMTONLY ON ' + @SqlQuery)


Additional reference:

System Function RAND() within UDF

Posted: September 15, 2010 in MSSQL
Tags:

Task: the system function RAND() use in the user defined function (UDF)
Solution: the system function RAND() is not possible to be used in the user defined function (see Figure 1 to 3). However, this function is possible to be implemented without problems into the stored procedure (see Figure 4 and 6), or to be used by means of a database object “view” ( see Figure 5 to 8 )

Figure 1: Definition of the Table-valued function
Figure 1: Definition of the Table-valued function

Figure 2: Result of SQL query (of the Table-valued and Scalar-valued function)
Figure 2: Result of SQL query (of the Table-valued and Scalar-valued function)

Figure 3: Definition of the Scalar-valued function
Figure 3: Definition of the Scalar-valued function

Figure 4: Definition of the stored procedure
Figure 4: Definition of the stored procedure

Figure 5: definition of the view
Figure 5: Definition of the view

Figure 6: Result of SQL query (of the stored procedure and view)
Figure 6: Result of SQL query (of the stored procedure and view)

Figure 7: Definition of SQL query using the view
Figure 7: Definition of SQL query using the view

Note: command GO 5 provides the execution of programming batch 5 times

Figure 8: Result of SQL query using the view
Figure 8: Result of SQL query using the view

Figure 9: Definition of SQL query with the pre-defined initialisation value
Figure 9: Definition of SQL query with the pre-defined initialisation value

Figure 10: Result of SQL query with the pre-defined initialisation value
Figure 10: Result of SQL query with the pre-defined initialisation value

Note: when entering the initialisation value, an identical result of random value will always be generated

SysObjects

Posted: August 15, 2010 in MSSQL
Tags:

sys.columns

Task: listing of the name and nullability of individual columns from the given table
Solution:

SELECT [name], [is_nullable]
FROM [sys].[columns]
WHERE [object_id] = OBJECT_ID('[dbo].[Test_SysColumns]')

Figure 1: Definition of the table
Figure 1: Definition of the table

Figure 2: Result of SQL query
Figure 2: Result of SQL query


sys.parameters

Task: listing of the I/O parameters from the given stored procedure
Solution:

SELECT [name], [is_output]
FROM [sys].[parameters]
WHERE [object_id] = OBJECT_ID('[dbo].[Test_SelInputParameters]')

Figure 3: Definition of the stored procedure
Figure 3: Definition of the stored procedure

Figure 4: Result of SQL query
Figure 4: Result of SQL query


INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE & INFORMATION_SCHEMA.TABLE_CONSTRAINTS

Task: listing of the name for a primary key (or primary keys) from the given table
Solution: see Figure 6

Figure 5: Definition of the table (see Figure 1)

Figure 6: Definition of SQL query
Figure 6: Definition of SQL query

Figure 7: Result of SQL query
Figure 7: Result of SQL query


ColumnsDefinition (INFORMATION_SCHEMA.COLUMNS)

Task: listing of the columns name, pre-defined value (suitably adjusted), nullability, data type and detailed information for data type from the given scheme and table. The objective is to provide this information for, e.g. validation logic at the application level of client application
Solution: see Figure 9

Figure 8: Definition of the table
Figure 8: Definition of the table

Figure 9: Definition of the stored procedure
Figure 9: Definition of the stored procedure

Figure 10: Definition of the user defined scalar function
Figure 10: Definition of the user defined scalar function

Figure 11: Result of the stored procedure
Figure 11: Result of the stored procedure

For the first time, DAC appeared in the SQL Server 2005 version. It enables one user from the sysadmins group (that means, the system administrator) to connect to the running instance of SQL Server Database Engine, especially for the purpose of solving occurred problems on the server (note: DAC connection will disconnect all other users from this server.) It will be used, e.g. in cases when the server does not respond to requirements coming from the client’s side but also in decrypting the content of database objects (i.e. of stored procedures, user-defined functions, views and triggers) which were encrypted using the key word WITH ENCRYPTION (note: the possibilities of content decryption by means of implicit encryption of  database objects will be dealt in some of other contributions on this topic.)

In the Express versions, this feature is implicitly deactivated. The procedure to allow DAC for the Express versions is as follows:

  • starting up of “Control Panel\System and Maintenance\Administrative Tools\Services”
  • stopping of “SQL Server Express” service
  • opening of the dialog window “Properties” on the suspended service
  • adding “-T7806” into the text box “Start parameters”
  • starting of the “SQL Server Express” service


DAC is available either through the SQLCMD utility (e.g. C:>SQLCMD -E -S.\SQLEXPRESS -A) or by means of SSMS (i.e. SQL Server Management Studio). A requirement is a need to use Query Editor with the ADMIN parameter for the server name (e.g. ADMIN:MP\SQLEXPRESS2008), while it is not possible to use the Object Explorer! The connection may be established direct from the given server only. No network connection to such a server is allowed.

Figure 1: Applet Services (Windows Vista)
Figure 1: Applet Services (Windows Vista)

Figure 2: SQL Server Properties (SQLS 2008)
Figure 2: SQL Server Properties (SQLS 2008)

Figure 3: Management Studio – failure of an attempt to DAC before allowing it (SQLS 2008)
Figure 3: Management Studio - failure of an attempt to DAC before allowing it (SQLS 2008)

Figure 4: Management Studio – failure of an attempt to DAC before allowing it (SQLS 2005)
Figure 4: Management Studio - failure of an attempt to DAC before allowing it (SQLS 2005)

Figure 5: Management Studio – failure of an attempt to DAC after allowing it through Object Explorer (SQLS 2008)
Figure 5: Management Studio - failure of an attempt to DAC after allowing it through Object Explorer (SQLS 2008)

Figure 6: SQLCMD – DAC performance (SQLS 2008)
Figure 6: SQLCMD - DAC performance (SQLS 2008)

Figure 7: SQLCMD – execution of a query in the database (SQLS 2008)
Figure 7: SQLCMD - execution of a query in the database (SQLS 2008)

Figure 8: SQLCMD – failure of an attempt to DAC after restarting the SQL Server service (SQLS 2008)
Figure 8: SQLCMD - failure of an attempt to DAC after restarting the SQL Server service (SQLS 2008)

Figure 9: Management Studio - DAC connection configuration through Query Editor (SQLS 2008)
Figure 9: Management Studio - DAC connection configuration through Query Editor (SQLS 2008)

Figure 10: Management Studio - execution of a query in the database through Query Editor (SQLS 2008)
Figure 10: Management Studio - execution of a query in the database through Query Editor (SQLS 2008)

Figure 11: Management Studio – a case when DAC is already used by other person (SQLS 2008)
Figure 11: Management Studio - a case when DAC is already used by other person (SQLS 2008)

Additional reference: