Author: way0utwest

  • A Joke Come True

    Yesterday was the opening of Microsoft Connect 2016. If you didn’t have the chance to watch the opening keynote, I’d recommend you do so. Mostly because one of my jokes, or perhaps a dream, has come true. SQL Server runs on Linux, and you now run it yourself. I know Microsoft has talked about this for most of 2016, and they have used it in demos, but there haven’t been public bits available.

    I’ve been lucky. In fact, I’ve been running SQL Server on Ubuntu since April of this year as part of a private program. I’ve been testing various Redgate Software tools as well as my demo code from presentations and so far everything has run. This includes the tSQLt framework and my tests that make use of SQLCLR. This includes my AlwaysEncrypted demos. I was very impressed that these features just worked, as though this instance were any other SQL Server that I had installed.

    What’s more, the installation and updating of SQL Server on Ubuntu, using apt-get, is far, far smoother than the installation on Windows. To be fair, this is a default installation, and I haven’t tried to set up all the various options and settings that are available on Windows. The various additional subsystems (SSIS, SSAS, SSRS, etc) aren’t available as well, but still, it’s a very smooth process. As I’ve updated various release candidates across the last few months, I run two commands: “apt-get update”, and “apt-get install mssql-server”.

    I don’t know if this is a good business decision for Microsoft. Time will tell, but I can’t help but think that the addition of another platform on which SQL Server can run is good for the product. More people will consider SQL Server as their database platform, with all of the powerful features and capabilities that brings to a database driven application. I suspect this will mean that many developers working in non-Microsoft environments with Linux, Java, PHP, and more will begin to consider SQL Server as an alternative to PostgreSQL and MySQL, in addition to Oracle and DB2. Certainly there is still a cost to using SQL Server, but it’s an incredibly powerful platform, one that now has a more consistent programming surface since almost all features are now available in Standard as well as Enterprise with SQL Server 2016 SP1. Getting RLS, Columnstore Indexes, In-Memory OLTP tables and more in all additions is a major win, and another of the pet peeves I’ve wanted changed for years.

    I am very interested to see how people view these changes, and if they will impact you? Do you want to run SQL Server on Linux? Since In-Memory OLTP and other features are now on Standard, are you interested in upgrading to SQL Server 2016 now? Perhaps you’re a little more excited about Microsoft and SQL Server with all of the new development changes announced yesterday? Let me know today.

    Steve Jones

     

  • #SQLNewBlogger – T-SQL ESCAPE for Wildcards

    Another post for me that is simple and hopefully serves as an example for people trying to get blogging as #SQLNewBloggers.

    I ran into a really interesting issue recently. I was working with a table and wanted to determine if the first character of a string was a left bracket. However, I discovered searching for a bracket isn’t as simple as I expected.

    Setup

    Here’s a mock table and some data.

    CREATE TABLE MyData
    ( myid INT IDENTITY(1,1),
    mychar VARCHAR(50)
    );
    GO

    INSERT dbo.MyData
    (mychar)
    VALUES
    (‘This is a string’),
    (‘”A Quoted String”‘),
    (”’Single quoted string”’),
    (”’more single quotes”’),
    (‘[My bracketed string]’),
    (‘[I like brackets]’),
    (‘Can I find [this] string?’)
    ;
    GO

    I wanted to return only rows 5 and 6 (based on identity) and not the others. My first thought was that I could just make a simple query.

    SELECT myid, mychar FROM mydata WHERE mychar LIKE ‘[%’

    The results:

    2016-11-11 18_20_37-SQLQuery5.sql - localhost_SQL2016.sandbox (PLATO_Steve (63))_ - Microsoft SQL Se

    That didn’t work. As soon as I got zero rows, I remembered that brackets allow me to wildcard part of a query. I need to escape the bracket, so I decided to try and do that with a repeating character, as we do with quotes.

    2016-11-11 18_21_41-SQLQuery5.sql - localhost_SQL2016.sandbox (PLATO_Steve (63))_ - Microsoft SQL Se

    Still not working. I searched, and there is an escape character of a backslash as well, but that didn’t help.

    2016-11-11 18_25_01-SQLQuery5.sql - localhost_SQL2016.sandbox (PLATO_Steve (63))_ - Microsoft SQL Se

    Now I was really curious. I checked the page for LIKE, and saw there was an ESCAPE option. I never knew this existed. I read the entry, but then when I looked at the samples, I was slightly confused. Why were they using an exclamation point?

    I read further and realized I hadn’t paid close attention. The escape character is the one I want to match up before the character I’m escaping. So I need to escape the trigger I’m going to use in front of the bracket.

    This is easier to show than explain. Here’s what I first did.

    2016-11-11 18_24_42-SQLQuery5.sql - localhost_SQL2016.sandbox (PLATO_Steve (63))_ - Microsoft SQL Se

    It looks like I’m escaping the bracket, but then why do I need two of them? If I remove one bracket, this doesn’t work (shown here).

    2016-11-11 18_26_32-SQLQuery5.sql - localhost_SQL2016.sandbox (PLATO_Steve (63))_ - Microsoft SQL Se

    What happens is the first left bracket is a trigger for the compiler to evaluate the next bracket as a literal, not a wildcard. If I replace the first bracket and the parameter with the exclamation point, this makes sense.

    2016-11-11 18_26_50-SQLQuery5.sql - localhost_SQL2016.sandbox (PLATO_Steve (63))_ - Microsoft SQL Se

    It’s not often I’ve had to search for brackets, but checking for percent signs has been common, and this is handy. I can’t believe I’ve never had to do this.

    #SQLNewBlogger

    Once I played with this in my code, I realized this was a neat function. I mocked up the table and it took longer to just type the words around the code than actually figure things out.

    This would be a nice short type of post for those of you that want to show you’ve learned a small thing.

    References

    LIKE – https://msdn.microsoft.com/en-us/library/ms179859.aspx

  • DLM Automation–Making a Database Connection

    One of the things I’ve been wanting to do is dig more into the command line automation cmdlets from the Redgate DLM Automation suite. While there are plugins for many build and release systems, I should be able to customize, or fall back, to the command line if necessary.

    Plus, this allows me to get a better feel for what’s happening at each step.

    This post looks at the basics of making a connection to a database. Note that this is documented on the DLM Automation 2 Cmdlet Reference page.

    New-Database Connection

    When I started working with the connections, I used the New-DatabaseConnection cmdlet. However, when I run this now, I get this:

    2016-10-14 15_32_04-DLM Automation–Making a Database Connection - Open Live Writer

    That’s fine, as my call to the new cmdlet works.

    2016-10-14 15_32_34-cmd - powershell

    Do I know what’s happening here? I should investigate further.

    First, if I’ve run this, what does it do? Not much, apparently. If I run an Extended Events session looking for a connection, I don’t get one. Let’s try a new command, this time using a name and password.

    2016-10-14 15_37_53-cmd - powershell

    That’s an invalid password for my instance (as it should be on every instance in the world). However, I don’t get an error. No connection was made. In this case, the cmdlet is storing off the connection credentials that will be used. If I don’t provide the user/password, then a trusted (Windows auth), connection is assumed.

    Can I now test this? Sure, I’ll use the Test-DLMDatabaseConnection to make a connection.

    2016-10-14 15_39_37-cmd - powershell

    This fails. That’s good to know. Now I can use this to actually determine if I target database is alive before I continue processing. My preferred method here would be to wrap this up in some error handling. For example, I can use a try..catch structure in PoSh. I’ll switch to the ISE to make this cleaner. Here’s the code

    try
    {
    Test-DlmDatabaseConnection -$test -ErrorAction Stop
    } 
    catch
    {
    Write-Host "error"
    }

    In the ISE:

    2016-10-14 16_22_45-Windows PowerShell ISE

    I can also get the error details from the current object ($_). Note, I’m not a PoSh expert, so if there are better ways, let me know.

    2016-10-14 16_36_48-Windows PowerShell ISE

    I can also pass in some common parameters, like –ErrorAction and –ErrorVariable. Then I can use these to decide whether or not to continue. In my case, I’ll just write a message. Here’s my code:

    $testconn = New-DlmDatabaseConnection -ServerInstance ".\SQL2014" -Database "st_integration" -U "sa" -Password "test"
    try
    {
    Test-DlmDatabaseConnection $testconn -ErrorAction SilentlyContinue -ErrorVariable ErrorHolder;
    } 
    catch
    {
    Write-Host $_.Exception.Message
    };
    
    if ($ErrorHolder)
    {
    Write-Host($ErrorHolder)
    }
    else
    {
    Write-Host("Everything works");
    }

    That will give me this:

    2016-10-14 16_41_08-Windows PowerShell ISE

    If I remove the user and password parameters, I get this:

    2016-10-14 16_41_29-Windows PowerShell ISE

    You didn’t think I’d publish the real sa password, did you? Of course not. If I change the code to the right password, things connect.

    Checking the Object

    What if I just want to check the object? Well, there are properties associated with the object. For example, if I use a simple variable to assign to the object, I can see some properties. If I just type the variable name, $testconn, I get these properties:

    • ServerInstance
    • Database
    • SQLServerCredential
    • ConnectionString
    • Description

    You can see these returned in a test session.

    2016-11-14 16_58_29-cmd - powershell

    Other Options

    I have other parameters I can use with my connection, or rather, in place of my connection object. I can use a connection string, with all of the parameters that are valid there. For example:

    2016-10-14 16_53_17-Windows PowerShell ISE

    If I enter the correct password, I get this:

    2016-10-14 16_54_09-Windows PowerShell ISE

    My connection string can contain all of the items I might normally use: ApplicationIntent, Encrypt, NetworkLibrary, etc. A full list of parameters is at: https://www.connectionstrings.com/all-sql-server-connection-string-keywords/

    The New-DlmDatabaseConnection object outputs a RedGate.DLMAutomation.Compare.SchemaSources.DatabaseConnection object, which is the input to quite a few other of the cmdlets. While not complex, it is worth understanding how to use this cmdlet, which is the basis for determining from which source or two which target you will be moving database changes.

    In another post, I’ll start to bind this cmdlet with others and actually perform some database deployment automation work.

  • Held Hostage by the Database

    Your database platform will constrain and limit the flexibility you have in evolving your software. It doesn’t matter which platform you choose, which type of database, or even the format for your data. At some point, you will be dealing with legacy data in some legacy schema or structure, and your development, and certainly deployment, will be slowed or impacted. Face it, the need to maintain state for your data is an impediment in a relational system. In a NoSQL or other store, the need to maintain code in your application that can interpret your data might be the issue over time.

    That’s not to imply this need to maintain state has to slow your development. On the contrary, there are many companies that find themselves moving quickly, able to make database changes on a weekly, or even daily, basis. There are multiple tricks and techniques for managing change, but ultimately the real secret is having a process that computers can follow and your developers adhere to.

    In other words, having some automation.

    Certainly you need to program the automation, or use tools like those from my employer, Redgate Software, but it doesn’t matter which what process you use. The process does need to be flexible because it will change over time. I can almost guarantee that the way in which you need to deploy code to the database in your environment will change over time. It has to as the needs and requirements of your business change.

    This means the way in which your developers need to build, test, and package changes will need to grow and evolve as well. While every developer and sysadmin needs to work within the process, the process does also need to be flexible as needs change. That isn’t to imply that your process should change every week, or for every deployment, but it will need to do so periodically, and hopefully, rarely.

    There are techniques to make deploying database changes easier on the developer and system administrator, but there are no magic techniques. All the tools I’ve encountered, including those from Redgate, do the same types of things you’d do manually. They just save you time and stress by helping you get set up and easily maintain your deployment tasks over time.

    Whether you use tools or not, please don’t allow the database to hold back your software development. Learn new ways to alter your database. Learn the ways to make changes to large tables. Learn how to avoid downtime. Just learn to design database changes in a better way and then automate the deployment of those changes.

    Steve Jones

    The Voice of the DBA Podcast

    Listen to the MP3 Audio ( 3.6MB) podcast or subscribe to the feed at iTunes and Libsyn.