Wednesday, 22 November 2017

SSMS versus SQL Operations Studio

SSMS vs SQLOpsStudio:

SQL Operations Studio (preview) is a free lightweight database development and operations tool that runs on your desktop and is available for Windows, macOS, and Linux. SQL Operations Studio (preview) has built-in support for Azure SQL Database, Azure SQL Data Warehouse, and SQL Server running on-premises or in any cloud. 

SQL Operations Studio (preview) offers a consistent experience across databases of your choice on your favorite operating systems.


SQL Server Management Studio is a fully featured database management tool that enables most DBA’s tasks. It will continue to be the flagship tool with the data tools portfolio. 
SQL Operations Studio enables most of the routine DBA tasks for development and operations of a database but does not have all of the functionality of SSMS. 
SQL Operations Studio is meant to be light weight and easy to use for non-professional DBAs and thus will most likely always optimize usability and light weight to addressing all corner cases.

Investments in flagship Windows tools (SSMS, SSDT, PowerShell) will continue in addition to the next generation of multi-OS and multi-DB CLI and GUI tools. 


The goal is to offer customers the choice of using the tools they want on the platforms of their choice for their scenarios.


Source: https://docs.microsoft.com/en-us/sql/sql-operations-studio/faq 

Wednesday, 8 November 2017

Windows Batch for getting today's date

for /F "skip=1 delims=" %%F in ('
    wmic PATH Win32_LocalTime GET Day^,Month^,Year /FORMAT:TABLE
') do (
    for /F "tokens=1-3" %%L in ("%%F") do (
        set CurrDay=0%%L
        set CurrMonth=0%%M
        set CurrYear=%%N
    )
)
set dd=%CurrDay:~-2%
set mm=%CurrMonth:~-2%
set yyyy=%CurrYear%

set today=%CurrYear%%CurrMonth:~-2%%CurrDay:~-2%

Friday, 20 October 2017

SQL Logic Operator Precedence: And and Or

And has precedence over Or, so, even if a <=> a1 Or a2
Where a And b 
is not the same as
Where a1 Or a2 And b,
because that would be Executed as
Where a1 Or (a2 And b)
and what you want, to make them the same, is
 Where (a1 Or a2) And b
Here's an example to illustrate:
Declare @x tinyInt = 1
Declare @y tinyInt = 0
Declare @z tinyInt = 0

Select Case When @x=1 OR @y=1 And @z=1 Then 'T' Else 'F' End -- outputs T
Select Case When (@x=1 OR @y=1) And @z=1 Then 'T' Else 'F' End -- outputs F

Monday, 24 July 2017

How to disable Data Compression on tables in whole database in SQL Server 2008R2?

If you restore database from enterprise edition to Standard edition and you have enabled "Data compression" on table, restoration fails. Data compression is available only Enterprise edition in SQL Server 2008R2. The best way how to disable data compression is the following:

1) make a clone of your database where data compression is enabled on enterprise edition

2) then run this script on clone database
SELECT
SCHEMA_NAME(sys.objects.schema_id) AS [SchemaName]
,OBJECT_NAME(sys.objects.object_id) AS [ObjectName]
,[rows]
,[data_compression_desc]
,[index_id] as [IndexID_on_Table]
into #compr
FROM sys.partitions
INNER JOIN sys.objects
ON sys.partitions.object_id = sys.objects.object_id 
WHERE data_compression > 0
AND SCHEMA_NAME(sys.objects.schema_id) <> 'SYS'
while exists(select 1 from #compr)
begin
      declare @i varchar(200) = (select top 1 [ObjectName] from #compr)
      print @i
     exec ('ALTER INDEX ALL ON '+@i + ' REBUILD WITH (DATA_COMPRESSION = None)')
     delete from #compr where [ObjectName] = @i
end
drop table #compr

3) now you can backup clone database and restore on Standard edition

Friday, 10 March 2017

How do you drop a default constraint in T-SQL ?

DECLARE @tableName VARCHAR(MAX) = '<MYTABLENAME>'
DECLARE @columnName VARCHAR(MAX) = '<MYCOLUMNAME>'
DECLARE @ConstraintName nvarchar(200)
SELECT @ConstraintName = Name 
FROM SYS.DEFAULT_CONSTRAINTS
WHERE PARENT_OBJECT_ID = OBJECT_ID(@tableName) 
AND PARENT_COLUMN_ID = (
    SELECT column_id FROM sys.columns
    WHERE NAME = @columnName AND object_id = OBJECT_ID(@tableName))
IF @ConstraintName IS NOT NULL
    EXEC('ALTER TABLE '+@tableName+' DROP CONSTRAINT ' + @ConstraintName)
Just replace <MYTABLENAME> and <MYCOLUMNNAME> as appropriate. 

Sunday, 5 June 2016


SQLCMD and the power of the little r

I would have to say that one of my favorite new utilities that shipped with SQL Server 2005 has been the SQLCMD utility.  I am going to demonstrate the use of include files. The following is the complete call syntax for SQLCMD.


sqlcmd 
[{ { -U login_id [ -P password ] } | –E trusted connection }] 
[ -z new password ] [ -Z new password and exit]
[ -S server_name [ \ instance_name ] ] [ -H wksta_name ] [ -d db_name ]
[ -l login time_out ] [ -A dedicated admin connection ] 
[ -i input_file ] [ -o output_file ]
[ -f < codepage > | i: < codepage > [ < , o: < codepage > ] ]
[ -u unicode output ] [ -r [ 0 | 1 ] msgs to stderr ] 
[ -R use client regional settings ]
[ -q "cmdline query" ] [ -Q "cmdline query" and exit ] 
[ -e echo input ] [ -t query time_out ] 
[ -I enable Quoted Identifiers ] 
[ -v var = "value"...] [ -x disable variable substitution ]
[ -h headers ][ -s col_separator ] [ -w column_width ] 
[ -W remove trailing spaces ]
[ -k [ 1 | 2 ] remove[replace] control characters ] 
[ -y display_width ] [-Y display_width ]
[ -b on error batch abort ] [ -V severitylevel ] [ -m error_level ] 
[ -a packet_size ][ -c cmd_end ] 
[ -L [ c ] list servers[clean output] ] 
[ -p [ 1 ] print statistics[colon format] ] 
[ -X [ 1 ] ] disable commands, startup script, enviroment variables [and exit] 
[ -? show syntax summary ]
:r is a SQLCMD command that parses additional Transact-SQL statements and sqlcmd commands from the file specified by <filename> into the statement cache.
A simple example:
In SQLQuery1.sql I have the following:
SELECT TOP 5 ProductID,Name,ProductNumber,MakeFlag FROM AdventureWorks.Production.Product
In SQLQuery2.sql I can then reference SQL file 1 as follows:
:r “c:\SQLQuery1.sql”
My results are:
ProductID    Name    ProductNumber    MakeFlag
1    Adjustable Race    AR-5381    0
2    Bearing Ball    BA-8327    0
3    BB Ball Bearing    BE-2349    1
4    Headset Ball Bearings    BE-2908    0
316    Blade    BL-2036    1

This may not seem like a big deal, but consider the following scenario. I have a large bat file of SQL that I process in jobs or in SSIS packages. This bat file is doing and setting the same variables over and over again, so I can create include files that declare my variables, and another include file that sets them.
My first file “c:\DeclareVariables.sql” will always change me to the correct DB, set no count on and declare my variables. This becomes  good anchor file for any pre-processing that I may want to do.
USE [AdventureWorks]
GO
SET NOCOUNT ON
GO
DECLARE @AccountingStartDate smalldatetime;
DECLARE @AccountingEndDate smalldatetime;
DECLARE @DocumentStatusText varchar(400);
DECLARE @Status tinyint;
“c:\SetVariables.sql” is where is set my variables. You notice that the SQL variable @Status is set to a SQLCMD variable of the same name “Status”. This allows me to control that from my batch sql file. I am trying to eliminate any hard coded references in my global files.
SET @Status = $(Status);
SET @AccountingStartDate = (SELECT AdventureWorks.dbo.ufnGetAccountingStartDate());
SET @AccountingEndDate = (SELECT AdventureWorks.dbo.ufnGetAccountingEndDate());
SET @DocumentStatusText = (SELECT AdventureWorks.dbo.ufnGetDocumentStatusText(@Status));
And finally the batch file “c:\SQLBatch.sql”. The first two lines set my include files to variables. This allows for a consistent naming through all my files and allows me to change the files without having to change the batch code. This is good for testing and portability. The next line is where I set the SQLCMD “Status” variable. This variable is then set in the SetVariables.sql file to the TSQL variable @Status that is passed to the function ufnGetDocumentStatusText.
:setvar DeclareVariablesScript "c:\DeclareVariables.sql"
:setvar SetVariablesScript "c:\SetVariables.sql"
 
-- Set Local variable Status (Used in SetVariablesScript)
:setvar Status 1
 
-- Declare Global Script Variables
:r $(DeclareVariablesScript)
-- Set Global Script Variables
:r $(SetVariablesScript)
 
SELECT * FROM AdventureWorks.Sales.SalesOrderHeader soh
WHERE ((soh.OrderDate > = @AccountingStartDate) AND (soh.OrderDate <= @AccountingEndDate));
GO
Now all I have to do it execute the file “c:\SQLBatch.sql”. If you are familiar with ASP include files this should be easy to understand.