Tag: SQLNewBlogger

  • #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

  • Creating a Logon Trigger–#SQLNewBlogger

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

    Suppose you want to audit logins for your SQL Server instance. There are multiple ways to do this, but Logon Triggers have a few advantages. First, they get data into a table that most of us are familiar with, SQL Server. Second, they guarantee that the event is captured on the instance if the trigger is enabled.

    There are plenty of other uses for these triggers, but beware that you can cause problems if your code doesn’t execute flawlessly.

    I’ll show you how to create a basic logon trigger here. Note, these are server level items, and you’ll need to be able to create the trigger in the master database.

    The structure of this code is similar to other triggers. We’ll use the CREATE TRIGGER DDL. Where this differs from DML triggers is that we use the ON ALL SERVER command. For auditing, I tend to set this as an EXECUTE AS ‘sa’, but you may choose a different type of account.

    Here’s my basic code:

    CREATE TRIGGER LogonTrigger
    --ALTER TRIGGER LogonTrigger
    ON ALL SERVER
    WITH EXECUTE AS 'sa'
    FOR LOGON
    AS
    BEGIN
        INSERT DBAAdmin.dbo.LoginAuditing
        SELECT SYSDATETIMEOFFSET(),
            ORIGINAL_LOGIN(),
            HOST_NAME(),
            APP_NAME();
    END;
    GO
    Note in this code  I’m specifying a specific table to store data in. This has to exist.

    I also use the FOR LOGON event. You can scope triggers for other events, at the server or database levels, and read more about DDL triggers in BOL.

    Once a user attempts to logon, the trigger fires and a simple insert takes place. If there are errors in inserting this data, the user may not be able to logon.

    There is a lot to write about logon triggers, but for this short piece, I’m just showing hot to get started. Please, please, please, be careful with these and read the documentation carefully. Be sure you understand how they work and how to disable them. If you implement one, test it extensively.

    SQLNewBlogger

    I had a small issue building a logon trigger, and thought I’d get a few posts written on the topic. This was 5 minutes work since I had the code and just wanted to describe things, but I’ve got a few more posts sketched on this topics  as I’ve learned more.

    Learning something, solving a problem, writing about it. This is a good way to show someone you are learning about a topic and developing some skill.

  • Output into a Table–#SQLNewBlogger

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

    I often see people struggling to use triggers for auditing, or having issues with building them to handle multi row updates. However, there’s another choice: the OUTPUT clause.

    Not many people use this clause, but it’s a great way to access the virtual inserted and deleted tables in your code.

    Suppose I have a simple insert statement like this one:

    2016-08-22 11_11_01-SQLQuery7.sql - (local)_SQL2014.Sandbox (PLATO_Steve (57))_ - Microsoft SQL Serv

    I want to ensure that I get the data inserted into an audit table. Certainly I could have code that does the insert into two places, like this:

    2016-08-22 11_13_40-SQLQuery7.sql - (local)_SQL2014.Sandbox (PLATO_Steve (57))_ - Microsoft SQL Serv

    But it can be hard to get developers to use procs like this, they might forget or need to build dynamic SQL. There are the other issues of maintenance where I might update the first INSERT, but forget the second.

    OUTPUT allows me to add a clause in my DML statement. I put this before the FROM clause, or in this case, before the Values clause. Then I include values from inserted or deleted along with any scalar values. That looks like this:

    2016-08-22 11_16_09-SQLQuery7.sql - (local)_SQL2014.Sandbox (PLATO_Steve (57))_ - Microsoft SQL Serv

    However, this returns the data to the console. What I’d really like is to put this into a table. For that reason, I then add an INTO clause, with my table name. Now when I execute this, I get the data from the inserted table added to my EmpAudit table.

    2016-08-22 11_18_32-SQLQuery7.sql - (local)_SQL2014.Sandbox (PLATO_Steve (57))_ - Microsoft SQL Serv

    A basic, quick look at the OUTPUT clause.

    SQLNewBlogger

    I ran into an issue with OUTPUT and realized that I hadn’t ever covered this basic concept for myself. As I learned a few things, I decided to write about OUTPUT. This took me about 10 minutes to cover the basics, and was part of a 30 minute session writing a few more pieces on OUTPUT.

  • Rounding Challenges–#SQLNewBlogger

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

    Rounding is an interesting activity, and one that I think people sometimes don’t pay enough attention to. Recently I saw a problem that intrigued me and I spent a few minutes looking at the issues.

    Let’s suppose you have data like this for pricing.

    0.3

    0.7

    1.2

    1.6

    How would you round this data? If you use a simple ROUND(n,0) function, you get this:

    0.0

    1.0

    1.2

    2.0

    Now, that’s fine, but what if you want this:

    0.3

    1.0

    1.2

    2.0

    That’s a bit more challenging. I’ll leave the solution out, but note that if I ROUND(n, 1), I get this.

    0.3

    0.7

    1.2

    1.6

    That’s not quite right either. ROUND() is using the number of decimals I’ve given it, but in some cases, I might want to round up. In this case, I only round up when we’re at .5 or higher, but don’t round down. In those cases, I need to limit rounding. This could be done in a WHERE clause, or with a function (be really careful of scalar functions).

    The important part is knowing that I really want this:

    ROUND(0.3, 1)

    ROUND(0.7, 0)

    ROUND(1.2, 1)

    ROUND(1.6, 0)

    How I get these is up to me, and there are a few ways, but really I want to be sure that I understand how ROUND() works and then apply it appropriately for my situation.

    SQLNewBlogger

    This is a quick one, literally about 6 minutes to write. About a minute of that was playing with formatting. Understanding functions, and knowing how they affect data is important to show your knowledge.

    Also, make sure that you know how to solve something like this if you write about it. I’d encourage you to write the solution as well as remember it. Someone might ask you in an interview Winking smile