Author: way0utwest

  • Common SQL Server Mistakes – Multi Row DML Triggers

    How often have you seen someone write a DML trigger like this:

    create trigger mytrigger on Mytable for insert as

    declare @id int
    select @id = id from inserted

    update xx set yyy = zz
    where id = @id

    return

    There seems to be this common misconception that a trigger fires for each change in a row (insert/update/delete), and that’s not true. As noted in Books Online, triggers fire once for the insert/update/delete. Typically this is an implicit transaction for the statement. If you have multiple statements inside an explicit transaction, the trigger fires once for each insert/update/delete statement in the transaction.

    That means that if I change two rows and I have the trigger above, I won’t get the behavior I expect from the trigger. Let’s say that I want to update my inventory table each time I change an order. Imagine that I have this in my orders table:

    orders_1

    and this in my inventory table.

    trigger_2

    If I now write this trigger:

    alter trigger orders_update_inventory on orders
      for update
      as

      declare @qty int
         ,    @product int
       
      select @qty = a.qty b.qty
        from inserted a
           inner join deleted b
             on a.orderid = b.orderid
      select @product = productid from inserted

      update inventory
       set onhand = onhand @qty
       where productid = @product

    return

    and execute this:

    update orders
      set qty = 2
       where orderid = ’59CD85CE-984C-4D33-9E23-5F6159848277′

    I will find that my inventory table looks like this:

    trigger_3

    That appears to work, but what happens if we execute this?

    update orders
      set qty = qty+1
      where[CustomerID int] = 2

    Then we find that the inventory is

    trigger_4

    In this case productID 1 has had its inventory reduced by 1, but not product ID 2. Why not?
    When the trigger fires, there are actually this data in the tables:

    Inserted
    OrderID  OrderDate  CustomerID int qty         productid
    ——– ———- ————– ———– ———–
    59CD…    2010-09-22 3              3           1
    01B6…    2010-09-22 2              2           2

    and deleted

    OrderID  OrderDate  CustomerID int qty         productid
    ——– ———- ————– ———– ———–
    59CD85…  2010-09-22 2              2           1
    01B66E…  2010-09-22 2              1           2

    However the trigger, in setting the variables to the result of a query could have picked either of the rows, but only one row. SQL Server doesn’t guarantee order without an ORDER BY, so either product ID could have been chosen. As a result, only one of the products had the inventory updated.

    A proper trigger would look like this

    alter trigger orders_update_inventory on orders
      for update
      as
         
      select @qty = a.qty b.qty
        from inserted a
           inner join deleted b
             on a.orderid = b.orderid
      select @product = productid from inserted

      update inventory
       set onhand = onhand ( a.qty b.qty)
       from inserted a
           inner join deleted b
             on a.orderid = b.orderid
       where inventory.productid = i.productid

    return

    Triggers should always be written to handle multiple rows, using the inserted and deleted tables for joins instead of variables. Even if you always just update single rows, coding this way will prevent issues if there is a multiple row change.

  • Community Direction

    When Microsoft implemented Connect, I thought it was a great idea. It was a way for real users to submit bugs, and others to see those bugs, voting on them if they thought they were important. It would help Microsoft determine what features and bugs are important and perhaps allocate resources accordingly. However there was a fundamental problem with the system. People would see individual items, and could vote for them, but wouldn’t have an idea of what other items might be listed.

    The work on SQL 11 is underway, and recently I got a note from Itzik Ben-Gan asking people to vote for windowing enhancements to the T-SQL language. I’m not sure exactly of all the places that these are useful, but Itzik is one of the smartest people I know and I tend to believe that if he finds these enhancements useful, they are likely going to make T-SQL easier to work with.

    But are these items a priority? I am sure they are valuable, but are they more valuable than CREATE or REPLACE? IS it more of a priority than allowing SSMS add-ins? There are any number of enhancements that are listed, but most of us don’t have the time to dig through them all, or even try to determine how important they might be when weighed against other items.

    Microsoft can do what they want, and they need to keep one eye on the sales generated from new features. However I wish that they’d reserve a slice of their development efforts for older features and get some community help in choosing which items to work on. I’d love to see a list of the items they are considering, maybe the top 20 features, and let us add votes to pick the 10 they can work on.

    We may not sign the purchase orders, but us DBAs really like SQL Server and would appreciate improvements that make our jobs easier.

    Steve Jones

    PS: Here are Itzik’s items:

  • Braindumps and Certification

    I saw a post recently that said that braindumps were the best way to prepare for certifications. It was posted from a certification vendor, so take it with a grain of salt, but I think a lot of people think this.

    That somewhat torques me off. I understand that certification can help someone get a better job, and it is good for a career. That’s fine, and I understand that if you are out of a job, or searching for a better job, that the price of the exam seems a little steep, and if you fail, you are out a decent amount of money. An exam costs $125 in the US, and that’s not an insignificant amount of money.

    However.

    We have enough people that don’t know what they’re doing. We have lots of people that struggle in their jobs, and often then don’t know what to do. Their bosses and co-workers aren’t happy. The struggle and get stressed, and they complain about their jobs. Stability is lower, software quality slides along the floor, and it’s a bad fit.

    Not everyone falls into this category, but having taken quite a few exams, I’d say that if you have some knowledge of SQL Server, and you work through a lot of exercises from any certification book, you’ll be fine. It’s hard, but it’s supposed to be. You’re supposed to be competent if you pass the exam.

    Finding ways to pass without being competent, or searching for a guarantee, isn’t good for your career. And it’s certainly not good for mine. Every person that passes who doesn’t really understand what they’re doing makes certifications that much more of a joke, and that much less valuable to employers.

    Which is the point for most people. They get the certification so that employers will be *more* likely to pay them more.

    Do yourself a favor. Study for the exam, learn how to handle the objectives, and then take your chances on the exam.

    There are a number of deals for second takes as well, so be on the lookout for those.

  • What Do We Need in SQL Server?

    What should be included in the next release of SQL Server? SQL Server 11 is being worked on now, and there are a number of features that I’m sure will be new, as well as some improvements to old features.

    But what should be changed/added/improved upon? Brad McGehee asked that question in his September Blog question. There are some really interesting ideas in the comments, and I hope that some of these get submitted to Connect for inclusion in SQL 11, or even SQL 12. The product will always need work, and we should all be looking forward to future versions.

    I think the product will evolve in the future, and include more Cloud-like features since SQL Azure is getting a lot of attention and it seems many vendors are looking to push for a more service oriented, cloud-based architecture. However for the foreseeable future, I’d think that the next few versions will continue with the same type of install-an-instance-on-a-server that we’ve been used to.

    If you have ideas, or want to lobby for new features, please feel free to include them in the discussion along with your reasons why they are a priority. And if they’re very important to you, please feel free to submit them on Connect and let us know the URL.

    Steve Jones