Quantcast
Channel: SQL Server Blog
Viewing all 1849 articles
Browse latest View live

Monday Coffee 2017-02-13

$
0
0

Man, if there was an award for procrastinating I’d definitely be in with a shout for today (I write these posts on the weekend). 

So I’m half writing this sitting on my balcony with a beer, one eye on the Italy v Ireland Six Nations game and trying not to think about all the work I should be doing. 

Anyway one thing I’ve been thinking about is documentation. Nobody likes doing it but oh boy did it help me out last week. 

We had one of our production servers fail during a RAM upgrade. No biggie as it was a passive node in a cluster but whilst we were writing up our steps to rebuild one of my colleagues forwarded a wiki page detailing the server’s configuration. Awesome stuff, we had a complete list of what we needed to do, the thing that made me laugh was that it was written….by me. 

I honestly don’t remember writing that document and yes, it was slightly out of date but it had steps on it which we would have completely forgotten to do if we didn’t have it. 

So yes, writing documentation sucks but it’s one of those chores that can really help you out. 

So don’t put it off, get that code/server spec/process documented. You’ll thank yourself in the end. 

Have a good week. 



What Does a DBA Do All Day?

$
0
0

It is clear to me that no one, except for database administrators, has any idea what a DBA does all day long:

The post What Does a DBA Do All Day? appeared first on Thomas LaRock.

If you liked this post then consider subscribing to the IS [NOT] NULL newsletter: http://thomaslarock.com/is-not-null-newsletter/

SQL SERVER – FIX: Msg 7356, Level 16 – The OLE DB provider “ASEOLEDB” for linked server “SYBASESERVER” supplied inconsistent metadata for a column

$
0
0

SQL SERVER - FIX: Msg 7356, Level 16 - The OLE DB provider "ASEOLEDB" for linked server "SYBASESERVER" supplied inconsistent metadata for a column close In SQL Server, we can create linked server to many other RDBMS. The providers to connect would generally publish by destination RBMS. In this client scenario, they were dealing with linked server to Sybase. Let us learn about the error The OLE DB provider “ASEOLEDB” for linked server “SYBASESERVER” supplied inconsistent metadata for a column.

Here is the query which was tried by the client.

SELECT * 
FROM SYBASESERVER.prodxc.dbo.sysobjects

It was failing with below error

Msg 7356, Level 16, State 1, Line 1
The OLE DB provider “ASEOLEDB” for linked server “ALTAIR” supplied inconsistent metadata for a column. The column “versionts” (compile-time ordinal 20) of object “prodxc.dbo.sysobjects” was reported to have a “DBCOLUMNFLAGS_ISFIXEDLENGTH” of 16 at compile time and 0 at run time.

Linked Server setup was as below:

  • Destination Server: Sybase Server:  SYBASESERVER:5000
  • Provider: SAP ASE OLE DB Provider

To troubleshoot, I asked them to execute the above query by changing the table name with some other tables within the system catalog.  Interestingly, we were able to successfully execute those queries with no issues.  So, the issue seems to be related to the specific table sysobjects.

Instead of four-part naming, we asked to try below OPENQUERY format of the linked server query.

SELECT * 
FROM OPENQUERY([SYBASESERVER], 'SELECT * FROM PRODXC.DBO.SYSOBJECTS')

Later we found that It appears that the Sybase OLE DB MDA provider on the Sybase server were not up to date.

WORKAROUND/SOLUTION

  1. Instead of four-part naming, use OPENQUERY
  2. Make sure that drivers on the client and server are up-to-date.

Reference: Pinal Dave (https://blog.sqlauthority.com)

First appeared on SQL SERVER – FIX: Msg 7356, Level 16 – The OLE DB provider “ASEOLEDB” for linked server “SYBASESERVER” supplied inconsistent metadata for a column

Azure Advisor Recommendations

$
0
0
Logging into the Azure portal is a daily task of mine and my eyes light up when I see features in preview mode. With that being said Azure Advisor Recommendations is what I will be writing about today. What is … Continue reading

SQL SERVER – FIX: Msg 15281- SQL Server Blocked Access to Procedure ‘sys.xp_cmdshell’ of Component ‘xp_cmdshell’

$
0
0

One of my blog readers pinged me on Skype and asked a simple question. I always thought I had a blog written about this error, but I was wrong. So, this blog is the outcome of a short interaction with my blog reader. Let us learn about how to fix blocked access error.

Hi Pinal,
I am getting below error in SQL.

Msg 15281, Level 16, State 1, Procedure xp_cmdshell
SQL Server blocked access to procedure ‘sys.xp_cmdshell’ of component ‘xp_cmdshell’ because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of ‘xp_cmdshell’ by using sp_configure. For more information about enabling ‘xp_cmdshell’, search for ‘xp_cmdshell’ in SQL Server Books Online.

Here is the command I am running.

xp_cmdshell 'dir c:\Windows'

We can easily reproduce the error if the setting is OFF.

SQL SERVER - FIX: Msg 15281- SQL Server Blocked Access to Procedure 'sys.xp_cmdshell' of Component 'xp_cmdshell' xp_cmd-error-01-800x85

As we can see that the error message is useful and tells what exactly needs to be done. But for someone who is new to SQL Server, above may not be enough.

SOLUTION / WORKAROUND

Here is the query we need to run in SQL Server Management Studio.

-- We need to have this ON because xp_cmdshell is an advanced option.
EXEC sp_configure 'show advanced options', 1
GO
-- To update the currently configured values for sp_configure
RECONFIGURE WITH OVERRIDE
GO
-- Now, enable the feature.
EXEC sp_configure 'xp_cmdshell', 1
GO
-- To update the currently configured values for sp_configure
RECONFIGURE WITH OVERRIDE
GO

After completing above query, we should be able to use xp_cmdshell without above error.

Reference: Pinal Dave (https://blog.sqlauthority.com)

First appeared on SQL SERVER – FIX: Msg 15281- SQL Server Blocked Access to Procedure ‘sys.xp_cmdshell’ of Component ‘xp_cmdshell’

True story: Encryption in progress stuck

$
0
0
Working with a couple of databases that needed TDE I noticed when I enabled one of them that it was stuck on “encryption in progress” for quite a while. Using the following query I confirmed the following: (source: https://msdn.microsoft.com/en-us/library/bb677274.aspx) My … Continue reading

SQL SERVER – Powershell Script – Remove Old SQL Database Backup Files from Azure Storage

$
0
0

SQL SERVER - Powershell Script - Remove Old SQL Database Backup Files from Azure Storage backupicon Few days back I wrote blog to help my blog reader and this is follow up on the same post How to Add Date to Database Backup Filename? – Interview Question of the Week #109. In this blog post we will see a powershell script for Removing Old SQL Database Backup Files from Azure Storage.

So, I added SQL Agent job in my SQL Server and forgot it. Later I realized that I am consuming space on my Azure storage and I need to clean up my old backups. If they were on disk, I would have created maintenance plan to clean them up, but since they are in Azure storage now, I need to write a PowerShell script to clean them up.

SOLUTION/WORKAROUND

Here is what I came up with.

$HowOldFile = [DateTime]::UtcNow.AddHours(-72)
$StorageAccountName = "<StorageAccountName>"
$StorageAccountKey = "StorageAccountKey>"
$Containername = "<ContainerName>"
$extension = "*.bak"
$Storagecontext = New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey
Get-AzureStorageBlob -Container $Containername -Context $context | Where-Object { $_.LastModified.UtcDateTime -lt $HowOldFile -and $_.BlobType -eq "PageBlob" -and $_.Name -like $extension} | Remove-AzureStorageBlob

You need to fill the parameters based on your configuration.

Notes

  1. To run above, you need to have Azure PowerShell cmdlets installed.
  2. It can be run from anywhere, not necessarily SQL Server machine because it has nothing to do with SQL Server.
  3. In the above script, I am checking the LastModified date for each blob with extension with *. back and deleting those which are 72 hours older. You need to change the extension and time.
  4. When you copy paste from a blog, it might not parse correctly, so take extra care for special characters.

Do you have any better script which can do the same? Please share via comments to help others.

Reference: Pinal Dave (https://blog.sqlauthority.com)

First appeared on SQL SERVER – Powershell Script – Remove Old SQL Database Backup Files from Azure Storage

The Future of Managing Databases in a Hybrid IT World

$
0
0
When you work in information technology long enough, you get to see how people react when something new comes along. Some people embrace change, even to the point of being an early adopter. Others might use a wait-and-see approach. And then there is the group of people who are afraid of change in any form. 

Read more at http://sqlmag.com/sql-server/future-managing-databases-hybrid-it-world


Gartner Magic Quadrant for BI 2017 Top 3 Rankings

$
0
0
This is a different spin on the top three vendor rankings visualized in Power BI.  According to the placement of the chart elements in the “Visionary/Leader” quadrant, Microsoft leads Tableau by a little over 36% in the “Vision Completeness “ score and Tableau beat out Microsoft on the “Ability to Execute” scale by just 1.09%.  I’ve … Continue reading

SQL SERVER – Cannot open backup device. Operating system error 1326 (Logon failure: unknown user name or bad password.)

$
0
0

There might be various reasons for above error, but this case is very specific to a situation where SQL Server was installed on a machine which was in Workgroup whereas the backup destination was the server located in the domain.  Here is the error message seen in SQL Agent job history. Let us learn about how to fix Operating system error 1326.

Executed as user: NT Service\SQLSERVERAGENT. Microsoft (R) SQL Server Execute Package Utility Version 11.0.2100.60 for 64-bit Copyright (C) Microsoft Corporation. All rights reserved.
Started: 12:23:24 PM Progress: 2016-12-27 12:23:25.00 Source: {229AB1E3-E7E5-4185-B305-BF0F7657122A}
Executing query “DECLARE @Guid UNIQUEIDENTIFIER EXECUTE msdb..sp…”.: 100% complete End Progress Error: 2016-12-27 12:23:25.35 Code: 0xC002F210 Source: Back Up Database Task Execute SQL Task
Description: Executing the query “BACKUP DATABASE [master] TO DISK = N’\\192.168.3….” failed with the following error: “Cannot open backup device ‘\\192.168.3.55\backupShare\master_backup_2016_12_27_122325_2407734.bak’. Operating system error 1326(Logon failure: unknown user name or bad password.). BACKUP DATABASE is terminating abnormally.”. Possible failure reasons: Problems with the query, “ResultSet” property not set correctly, parameters not set correctly, or connection not established correctly. End Error

Generally, when the backup is taken SQL Agent Service account is used to take backup. In this case since SQL was on Workgroup, it was NT Service\SQLSERVERAGENT. This account is not a valid account to validate for a domain.

SQL SERVER - Cannot open backup device. Operating system error 1326 (Logon failure: unknown user name or bad password.) bad-password-800x185

VERIFICAITON

First, let’s verify that we are hitting the same issue which I experienced. From Workgroup machine, we would try to query remote share using xp_cmdshell. Here is the command.

xp_cmdshell 'dir \\192.168.3.55\backupShare'

This command should fail with below error.

Logon failure: unknown user name or bad password.

SOLUTION

Since we are talking about authentication issue. So, we need to make sure that we map a drive to SQL Server (not windows). As per SQL Server Books-On-Line:

“For a network share to be visible to SQL Server, the share must be mapped as a network drive in the session in which SQL Server is running”

Here is the command to map the drive.

EXEC XP_CMDSHELL 'net use Z: \\192.168.3.55\backupShare password@123 /User:domain\user'

Once the above is completely successful, we should be able to see content on the Z drive by running below command.

EXEC XP_CMDSHELL 'dir Z:\'

After this we should be able to take backup on the Z drive as its mapped within SQL Server as a drive.

Backup database master to disk = 'Z:\master.bak'

The above command should work and create the backup file in \\192.168.3.55\backupShare

Have you encountered this error earlier? Did you find this solution interesting? Please comment and let me know.

Reference: Pinal Dave (https://blog.sqlauthority.com)

First appeared on SQL SERVER – Cannot open backup device. Operating system error 1326 (Logon failure: unknown user name or bad password.)

How to Keep Certain Records on Top While Ordering Data? – Interview Question of the Week #110

$
0
0

Question: How to Keep Certain Records on Top While Ordering Data?

Let me elaborate this question as it is originally received.

“Hi Pinal,

I just returned from an interview and I faced a very strange question. I was asked following question and I do not know how to answer.

The interviewer has asked that if I can somehow keep one record on the top of the result set when I order the data. How can I do it?

For example, please see following example where I have four cities. What I want is that I want to keep the data of one city on the top and order the rest how the data by city name, how can I do it?”

Here is the image (I have recreated the image) to explain the problem.

How to Keep Certain Records on Top While Ordering Data? - Interview Question of the Week #110 orderdata

This is a very interesting problem and now let us see the solution for the same.

Answer:

In Order by clause you can use a number which will indicate the ordinal position of the column name used in the select statement. For example Order by 2 means order by the second column values specified in the SELECT statement. However it would be different if used in CASE expression.

Let us create this simple table and explore this

CREATE TABLE #cities(city_id INT, city_name VARCHAR(100))
INSERT INTO #cities(city_id,city_name)
SELECT 1,'Chennai' UNION ALL
SELECT 2,'New Delhi' UNION ALL
SELECT 3,'Mumbai' UNION ALL
SELECT 4,'Kolkata' 
GO

Let us retrieve the data as it is from the table.

SELECT * 
FROM #cities 
GO

How to Keep Certain Records on Top While Ordering Data? - Interview Question of the Week #110 order1

Now let us retrieve the data by adding additional order by clause.

SELECT * 
FROM #cities 
ORDER BY city_name
GO

How to Keep Certain Records on Top While Ordering Data? - Interview Question of the Week #110 order2

You can see that in the result set we have record Mumbai as a third record. Let us see if we can move that particular order on the top of the result set while keeping the result of the city name ordered alphabetically.

Now let us execute the following statement where I have used a case statement in the ORDER BY clause and it will make sure that city name Mumbai stays on the top of the resultset and the rest of the data is ordered by by city name.

SELECT * 
FROM #cities 
ORDER BY 
	CASE WHEN city_name = 'Mumbai' 
	THEN 1
		ELSE 2 END , 2
GO

How to Keep Certain Records on Top While Ordering Data? - Interview Question of the Week #110 order3

Here CASE expression is used in the ORDER BY clause. It will show you “Mumbai” on top, followed by other cities. The CASE expression assigns the literal value 1 or 2 based on the condition. Mumbai will have 1 and others will have 2. The number 2 followed by the CASE expression indicates the usual meaning (Order by the second column). So at the end, Mumbai comes first and the rest of the city in ascending order

So in ORDER BY clause, a number in a CASE expression assigns a literal value and a number without CASE expression indicates the ordinal position of the column name.

You can also do this with the help of UNION but I have found this much simpler option for ordering data.

Reference: Pinal Dave (http://blog.SQLAuthority.com)

First appeared on How to Keep Certain Records on Top While Ordering Data? – Interview Question of the Week #110

SQL SERVER – Fix: Error 946, Severity: 14 – Cannot open database ‘DB’ version 782. Upgrade the database to the latest version

$
0
0

I was consulting a client for migration from SQL 2014 to SQL 2016. They were using methodology discussed in books online here. https://msdn.microsoft.com/en-us/library/dn178483.aspx (Upgrading AlwaysOn Availability Group Replica Instances). Let us learn about how to fix error 946.

While doing that, they noticed that once they added SQL Server 2016 as secondary replica everything was looking great, but availability database on SQL Server 2016 were stuck in Synchronized / In Recovery in SSMS.

SQL SERVER - Fix: Error 946, Severity: 14 - Cannot open database 'DB' version 782. Upgrade the database to the latest version alwayson-upgrade-01

I have asked them to check SQL Server ERRORLOG on the secondary replica (SQL Server 2016) and found below the message.

Error: 946, Severity: 14, State: 1.
Cannot open database ‘ProdDB’ version 782. Upgrade the database to the latest version.

I asked to check sys.sysdatabases using below

SELECT name, version 
FROM sys.sysdatabases

SQL SERVER - Fix: Error 946, Severity: 14 - Cannot open database 'DB' version 782. Upgrade the database to the latest version alwayson-upgrade-02

Since databases are part of availability group and have not been recoveredvered yet, it’s expected to see that version and state as “In recovery”. Once we have failed over the databases to secondary replica and made it as primary everything was looking good and database on SQL 2012 were shown as Not Synchronizing because SQL Server doesn’t allow database secondary replicaplica to be of lower version.

One thing which I noticed is that once I upgraded old primary to SQL 2016 then also databases were not getting synchronized. To fix that I must run below command on current secondary replica which is now upgraded to SQL 2016.

ALTER DATABASE [SQLAuthority] SET HADR RESUME;

Have you ever done upgrade of SQL in AlwaysOn availability group? How was your experience?

Reference: Pinal Dave (http://blog.SQLAuthority.com)

First appeared on SQL SERVER – Fix: Error 946, Severity: 14 – Cannot open database ‘DB’ version 782. Upgrade the database to the latest version

Monday Coffee 2017-02-20

$
0
0

No rugby on last weekend so I didn’t have anything to distract me from working. On another note, my flat has never been cleaner!

So last week Microsoft announced Availability Groups for SQL Server on Linux.

This is a big announcement as one of the first things I noticed when playing around with a SQL instance on Linux was the lack of high availability features. (I wrote a post on manually setting up transaction log shopping here).

Microsoft hasn’t released a stripped down version of Availability Groups either. They’ve said in the post that:-

all capabilities that make Availability Groups a flexible, integrated and efficient HADR solution are available on Linux as well

So are we looking at SQL on Linux moving towards an edition that will rival its windows counterpart in features and usability? I think that’s what Microsoft’s end goal will be, a platform independent relation database system.

That for us as SQL Server DBAs mean interesting times ahead. In the future not only will we be looking at the usual options when building our SQL Server instances, we’ll be looking at the pros and cons of the supporting operating system and then making our decisions. Could lead to some interesting design room discussions.

I’ve said before that I think this is great. It’s opening up a whole new world to me as a DBA, I love learning new areas of technology so I can’t wait to get my hands on this and start playing around.

Have a good week!


Setting up SQL Server to SQL Database (Azure) Replication

$
0
0
I had a need to setup transactional replication from my SQL Server to SQL Database (Azure) where I only needed a selection of tables that I wanted to off-load to Azure.  For this post I will be going through the … Continue reading

SQL Slammer Is Back. Here’s What You Need to Know


SQL Server vNext: sys.dm_db_stats_histogram

$
0
0
Since installing SQL Server vNext CTP 1.3 I found out that there is a new way to return statistics histogram for a specific stat which actually is also available with the latest Cumulative Update for SQL Server 2016 Service Pack … Continue reading

SQL SERVER – Error 17113, Severity: 16 – Error Occurred While Opening File ‘master.mdf’ to Obtain Configuration Information at Startup

$
0
0

SQL SERVER - Error 17113, Severity: 16 - Error Occurred While Opening File 'master.mdf' to Obtain Configuration Information at Startup errorcode While playing with my SQL Server startup parameter, I made some mistakes and came to a situation where SQL Server was not getting started. In this blog post, let us learn about error 17113.

Whenever you have a situation where SQL is not getting started, what you would normally do?

  1. Look at ERRORLOG, if generated.
  2. Look at System Event Log.
  3. Look at Application Event log.

In my case, I was lucky enough that the SQL ERRORLOG file was getting generated. SQL SERVER – Where is ERRORLOG? Various Ways to Find ERRORLOG Location

Here is what I have in Errorlog.

2016-12-28 01:20:42.27 Server Registry startup parameters:
-m C:\Program Files\Microsoft SQL Server\MSSQL13.SOFTWARE\MSSQL\DATA\master.mdf
-e C:\Program Files\Microsoft SQL Server\MSSQL13.SOFTWARE\MSSQL\Log\ERRORLOG
-l C:\Program Files\Microsoft SQL Server\MSSQL13.SOFTWARE\MSSQL\DATA\mastlog.ldf
2016-12-28 01:20:42.27 Server Command Line Startup Parameters:
-s “SOFTWARE”
2016-12-28 01:20:42.28 Server Error: 17113, Severity: 16, State: 1.
2016-12-28 01:20:42.28 Server Error 3(The system cannot find the path specified.) occurred while opening file ‘master.mdf’ to obtain configuration information at startup. An invalid startup option might have caused the error. Verify your startup options, and correct or remove them if necessary.
2016-12-28 01:20:42.28 Server SQL Server shutdown has been initiated

Do you find something interesting? If you are thinking that master.mdf file is not present in C:\Program Files\Microsoft SQL Server\MSSQL13.SOFTWARE\MSSQL\DATA\ then you are incorrect.

If the file was not present, here is how the ERRORLOG would look like.

2016-12-28 01:26:49.12 Server Registry startup parameters:
-d C:\Program Files\Microsoft SQL Server\MSSQL13.SOFTWARE\MSSQL\DATA\master.mdf
-e C:\Program Files\Microsoft SQL Server\MSSQL13.SOFTWARE\MSSQL\Log\ERRORLOG
-l C:\Program Files\Microsoft SQL Server\MSSQL13.SOFTWARE\MSSQL\DATA\mastlog.ldf
2016-12-28 01:26:49.12 Server Command Line Startup Parameters:
-s “SOFTWARE”
2016-12-28 01:26:49.13 Server Error: 17113, Severity: 16, State: 1.
2016-12-28 01:26:49.13 Server Error 2(error not found) occurred while opening file ‘C:\Program Files\Microsoft SQL Server\MSSQL13.SOFTWARE\MSSQL\DATA\master.mdf’ to obtain configuration information at startup. An invalid startup option might have caused the error. Verify your startup options, and correct or remove them if necessary.

Do you see the difference?

SOLUTION

In my case, the file was present in the location, but the parameter name was wrong. SQL Server uses -d for the master database mdf file. As I hinted earlier, I changed the parameter and now if you notice again the parameter is -m which is not a valid parameter for the master database data file. We can modify the startup parameters via configuration manager. Step is already listed here.

Hope you have learned something new.

Reference: Pinal Dave (http://blog.SQLAuthority.com)

First appeared on SQL SERVER – Error 17113, Severity: 16 – Error Occurred While Opening File ‘master.mdf’ to Obtain Configuration Information at Startup

Quick Tips:- Add SQL User/Rolemember to all Databases in SQL Server

$
0
0
Most of times when you have dedicated SQL Server for an Application clients come up with a request to add a user to all databases in the SQL Server with certain permission, while its east to do it via SSMS for if the system has only couple of databases but imagine your SQL instance have hundreds of databases then scripting is the way to go, I have assumed the login name is ‘Test’client has request db_datareader and db_datawriterpermission for our example blog,

There are 2 ways I am going to accomplish this one using TSQL and another using Powershell.

TSQL:-
--Add User
EXEC sp_MSforeachdb 'USE ?;CREATE USER Test FOR LOGIN Test'
GO
--Add Role member
EXEC sp_MSforeachdb 'USE ?;ALTER ROLE db_datareader ADD MEMBER Test'
GO
--Add Role member
EXEC sp_MSforeachdb 'USE ?;ALTER ROLE db_datawriter ADD MEMBER Test'

Powershell:-

Clear-Host

Import-ModuleSQLPS-DisableNameChecking-ErrorActionSilentlyContinue
$srv=New-Object"Microsoft.SqlServer.Management.Smo.Server""1MKBG12"
$dbs=$srv.databases


$loginname='Test'##########Provide Login name to check#############


$chkloginflag=$null
$chkloginflag=$srv.Logins|where {$_.name -eq'Test3'}
if($chkloginflag-eq$null-or$chkloginflag-eq'')
{
      $login=New-Object ('Microsoft.SqlServer.Management.Smo.Login') ($srv, $loginname)
      $login.LoginType='SqlLogin'#https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.management.smo.logintype.aspx
      $login.PasswordExpirationEnabled=$false
      $Login.PasswordPolicyEnforced=$false
      $login.Create("test")

      forEach($dbin$dbs)
      {
            $usr=New-Object ('Microsoft.SqlServer.Management.Smo.User') ($db, $loginname)
            $usr.create()
            $usr.AddToRole("db_datareader")
            $usr.AddToRole("db_datawriter")
      }
}


The above PowerShell script also creates a Login if it does not exist then creates the SQL user in all databases with reader and writer roles. I have written a simple script assuming the Login to be SQL Authentication. You can tweak the $Login object to create Windows User/Group Login.







SSMS Presenter Mode

$
0
0
SQL Server Management Studio (SSMS) release candidate 17.0 RC2 works side-by-side with generally available releases (16.x), but it is not recommended for production use. There are many enhancements which you can read here: https://docs.microsoft.com/en-us/sql/ssms/sql-server-management-studio-ssms-release-candidate but there is one feature I … Continue reading

A Program to Find INSERT Statements That Don’t Specify Columns

$
0
0

Unlike mathematical relations, SQL tables have ordered columns, but please don’t depend on it.
In other words, try to treat these tables as the same because it’s super-awkward to turn one into the other:

CREATETABLE PEOPLE
(
    LastName varchar(200),
    FirstName varchar(200))
CREATETABLE PEOPLE
(
    FirstName varchar(200),
    LastName varchar(200))

Don’t Omit Column Specification

And don’t forget to specify the columns in your INSERT statement. No excuses.

All the columns!

You’re depending on the column ordering if you write INSERT statements like this:

INSERT PEOPLE /* no column spec */VALUES('Rob', 'Farley'),
       ('Angela', 'Henry'),
       ('Andy', 'Leonard'),
       ('Richard', 'Douglas'),
       ('David', 'Maxwell'),
       ('Aaron', 'Nelson'),
       ('Paul', 'Randal');

We recently got burned by something like this

Find Missing Column Specifications

Thomas LaRock recently encouraged DBAs to branch out horizontally. In that spirit, don’t be too afraid of the C#. I’ve got a program here that finds procedures with missing column specifications.

  • If for some reason, you don’t care about enforcing this rule for temp tables and table variables, then uncomment the line // visitor.TolerateTempTables = true;
  • It uses ScriptDom which you can get from Microsoft as a nuget package.
  • The performance is terrible in Visual Studio because ScriptDom uses Antlr which uses exceptions for flow control and this leads to lots of “first chance exceptions” which slows down debugging. Outside of Visual Studio, it’s just fine.
usingSystem;usingSystem.Collections.Generic;usingSystem.Data.SqlClient;usingSystem.Linq;usingMicrosoft.SqlServer.TransactSql.ScriptDom; 
class Program { 
    staticvoid Main(string[] args){ 
        SqlConnectionStringBuilder builder =new SqlConnectionStringBuilder {
            DataSource =".",
            InitialCatalog ="test_database",
            IntegratedSecurity =true}; 
        using(SqlConnection conn =new SqlConnection(builder.ToString())){
            conn.Open();
            SqlCommand command =new SqlCommand(@"
                SELECT OBJECT_SCHEMA_NAME(object_id) [schema], 
                       OBJECT_NAME(object_id)        [procedure], 
                       OBJECT_DEFINITION(object_id)  [sql]
                  FROM sys.procedures 
                 ORDER BY OBJECT_SCHEMA_NAME(object_id), OBJECT_NAME(object_id) ;", conn);
            SqlDataReader reader = command.ExecuteReader();while(reader.Read()){string schema = reader["schema"].ToString();string procedure = reader["procedure"].ToString();string sql = reader["sql"].ToString();if(SqlHasInsertWithoutColumnList(sql)){
                    Console.WriteLine( $"{schema}.{procedure}");}}}} 
    staticbool SqlHasInsertWithoutColumnList(string SQL){
        SQLVisitor visitor =new SQLVisitor();// visitor.TolerateTempTables = true;
        TSql130Parser parser =new TSql130Parser(true);
        IList<ParseError> errors;var fragment = parser.Parse(newSystem.IO.StringReader(SQL), out errors);
        fragment.Accept(visitor);return visitor.HasInsertWithoutColumnSpecification;}} 
internalclass SQLVisitor : TSqlFragmentVisitor {publicbool HasInsertWithoutColumnSpecification {get;set;}publicbool TolerateTempTables {get;set;} 
    publicoverridevoid ExplicitVisit(InsertStatement node){if(node.InsertSpecification.Columns.Any())return; 
        var source = node.InsertSpecification.InsertSourceas ValuesInsertSource;if(source !=null&& source.IsDefaultValues)return; 
        if(TolerateTempTables){var target = node.InsertSpecification.Targetas NamedTableReference;if(target !=null&&!target.SchemaObject.BaseIdentifier.Value.StartsWith("#")){
                HasInsertWithoutColumnSpecification =true;}}else{
            HasInsertWithoutColumnSpecification =true;}}}

In my environment, I found twelve examples which I’ll be fixing soon.

Viewing all 1849 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>