{"id":111987,"date":"2026-08-24T12:00:00","date_gmt":"2026-08-24T12:00:00","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=111987"},"modified":"2026-08-17T12:37:24","modified_gmt":"2026-08-17T12:37:24","slug":"9-things-i-wish-sql-server-had-and-why-theyd-matter","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/9-things-i-wish-sql-server-had-and-why-theyd-matter\/","title":{"rendered":"9 things I wish SQL Server had (and why they&#8217;d matter)"},"content":{"rendered":"\n<p><strong>Anyone who&#8217;s spent years writing T-SQL has a mental list of &#8220;why doesn&#8217;t SQL Server just do this already?&#8221; moments. Here are 9 of those from Louis Davidson&#8217;s perspective &#8211; a wish list of practical, coding-oriented feature requests drawn from real-world pain points. <\/strong><\/p>\n\n\n\n<p>When I was asked about doing a post like this, I looked around at similar articles to make sure I wasn\u2019t going to just repeat everyone\u2019s list verbatim. I checked out <a href=\"https:\/\/www.brentozar.com\/archive\/2025\/11\/i-wish-sql-server-had-these-four-innovations\/\" target=\"_blank\" rel=\"noreferrer noopener\">Brent Ozar\u2019s<\/a> post (and definitely agreed that I would like to be able to write the <code>FROM<\/code> clause first), and <a href=\"https:\/\/www.sommarskog.se\/wishlist.html\" target=\"_blank\" rel=\"noreferrer noopener\">Erland Sommarskog<\/a> has a huge list &#8211; a few of which overlap with mine.<\/p>\n\n\n\n<p>This backwards take on what <a href=\"https:\/\/straightpathsql.com\/5-things-sql-server-should-drop\/\" target=\"_blank\" rel=\"noreferrer noopener\">Mike Walsh<\/a> would like dropped from SQL Server, this 6-year-old <a href=\"https:\/\/www.reddit.com\/r\/SQL\/comments\/j696c8\/what_is_your_wishlist_for_sql_server_new_features\/\" target=\"_blank\" rel=\"noreferrer noopener\">Reddit thread<\/a> that still has some valid points, as well as a hopefully humorous take here by <a href=\"https:\/\/weblogs.sqlteam.com\/jeffs\/2005\/05\/24\/5248\/\" target=\"_blank\" rel=\"noreferrer noopener\">Jeff Smith<\/a>, are other samples of what I discovered during my search.<\/p>\n\n\n\n<p>There&#8217;s also the recent wish lists from <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/5-t-sql-features-that-should-already-exist-2026-sql-server-wish-list\/\" target=\"_blank\" rel=\"noreferrer noopener\">Ed Pollack<\/a> (I disagree with arrays, but <em>strongly<\/em> agree with an <code>OVERLAPS<\/code> operator!) and <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/whats-missing-in-t-sql-heres-my-t-sql-wish-list-of-features-that-developers-actually-need-in-sql-server\/\" target=\"_blank\" rel=\"noreferrer noopener\">Greg Low<\/a> here on Simple Talk. <\/p>\n\n\n\n<p>Finally, I stopped looking around when I found&nbsp;<a href=\"https:\/\/www.kevinrchant.com\/2019\/09\/03\/t-sql-tuesday-118-your-fantasy-sql-feature\/\" target=\"_blank\" rel=\"noreferrer noopener\">Kevin Chant\u2019s<\/a> T-SQL Tuesday post on the topic. It occurred to me that, aside from Erland&#8217;s post (and <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/t-sql-programming-sql-server\/five-changes-to-sql-server-id-love-to-see\/\" target=\"_blank\" rel=\"noreferrer noopener\">Aaron Bertrand\u2019s <\/a>list from early 2025), none of them have a lot in common with my desires for SQL Server. They are, as you will see, always coding-oriented.<\/p>\n\n\n\n<p>So, <strong>here are 9 things I wish SQL Server had<\/strong> &#8211; and a couple of them are kind of, <em>sort of<\/em>, multiples. They are mostly unordered as to which I would beg for first, though I will admit that the first one listed here is something I have asked about for over 20 years. In fact, back in 2005, it was said they would look at it for the &#8220;next&#8221; version&#8230;!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-system-managed-columns-in-sql-server\">System managed columns in SQL Server<\/h2>\n\n\n\n<p>One of the things I want in most every table I create are (what I call) \u201cphysical-only\u201d columns. I want to set a value (which will be set when a row is created and\/or updated) that doesn&#8217;t really matter to the user and should only ever be modified by the system. This might be the current user, application, time, an initial value from a different column, or whatever I need for a given situation.<\/p>\n\n\n\n<p>For example, I would like to be able to implement a simple <code>row_created_time<\/code> and <code>row_modified_time<\/code> using syntax more or less like the following:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">CREATE TABLE TableX\n(\n    \u2026 -- user columns\n     row_created_time  DATETIME2(0) NOT NULL \n            GENERATED ON INSERT AS (SYSDATETIME()),\n    row_modified_time DATETIME2 (0) NOT NULL\n            GENERATED ON INSERT, UPDATE AS (SYSDATETIME())  \n)<\/pre><\/div>\n\n\n\n<p>Now, whenever a row is added to <code>TableX<\/code>, both <code>row_created_time<\/code> <em>and<\/em> <code>row_modified_time<\/code> will be set to the current local time for the server. Whenever the row is updated, just the <code>row_modified_time<\/code> would be set.<\/p>\n\n\n\n<p>In some ways, you might think this would be best done by giving us access to some metadata about the lifecycle of rows in our tables. That is true &#8211; however, I want complete control if possible. I want to be able to set the time, round it off, fill this with a random number, just add 1 to the previous value, etc.<\/p>\n\n\n\n<p>Of course, all of this can be done with an <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/database-administration-sql-server\/sql-server-triggers-good-scary\/#:~:text=Triggers%20may%20be%20defined%20as,to%20be%20managed%20via%20triggers.\" target=\"_blank\" rel=\"noreferrer noopener\"><code>INSTEAD OF<\/code> trigger<\/a>, but it&#8217;s a lot of work to keep <code>INSTEAD OF<\/code> triggers maintained as the structure of a table is changed over time. <\/p>\n\n\n\n<p>Using an <code>AFTER<\/code> trigger, on the other hand, is less work, but has the downside that you must update the same row twice. That means &#8211; if you are using a feature like mentioned in the next section &#8211; more history recorded.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-user-defined-temporal-tables-in-sql-server\">User-defined temporal tables in SQL Server<\/h2>\n\n\n\n<p><a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/t-sql-programming-sql-server\/converting-a-history-table-into-a-system-versioned-temporal-table\/\" target=\"_blank\" rel=\"noreferrer noopener\">System versioned temporal tables<\/a> have been a part of SQL Server since 2016 and are awesome to help you see <em>what<\/em> has changed in your data over time. My coworkers and I love them. You can just ask <em>\u201cwhen the heck did this change, and what was the previous value?\u201d<\/em>, and the data is right there!<\/p>\n\n\n\n<p>Once you&#8217;ve set up a table as a system versioned temporal table, it just takes a simple <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/writing-an-efficient-query\/\" target=\"_blank\" rel=\"noreferrer noopener\">query<\/a> to see the history of changes for a row. While it complicates the process of managing the table structure as it changes, it&#8217;s a great way to <em>track<\/em> those changes over time.<\/p>\n\n\n\n<p>The problem is, you have little control over the data in the history table (at least while history capture is enabled). It&#8217;s just an automatic process that captures every single change. Even the non-effective ones are captured, like when you update the same row multiple times at the same time, or in the same transaction.<\/p>\n\n\n\n<p>That automatic process stamps the row with the time in the system when the row was changed. This is a problem because the system time is only <strong>when the change occurred in your database<\/strong> &#8211; not when the actual thing happened outside of the SQL database <a href=\"https:\/\/en.wikipedia.org\/wiki\/Data_manipulation_language\" target=\"_blank\" rel=\"noreferrer noopener\">DML (data manipulation language)<\/a> operation.<\/p>\n\n\n\n<p>While system-defined temporal tables are wonderful for tracking DML modifications, they are <em>not<\/em> ideal for usage where you need any control over the past. For example, if you determine that an address was misspelled in past data, you can\u2019t simply update it without disabling system versioning. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-what-happens-if-you-attempt-to-update-the-history-table-in-sql-server\">What happens if you attempt to update the history table in SQL Server?<\/h3>\n\n\n\n<p>If you <em>do<\/em> attempt to update the history table, you&#8217;ll get this error:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">Msg 13561, Level 16, State 1, Line 54 Cannot update rows in a temporal\nhistory table 'tempdb.dbo.tablename'.<\/pre><\/div>\n\n\n\n<p>The same can be said of the time of the change. When tracking DML changes, you want to set the time at the exact moment you make the change. But, if you want changes to appear as if they occur at the end of the day, for example, this can\u2019t be done <em>and<\/em> still use the <code>AT SYSTEM TIME<\/code> construct. Again, you&#8217;d have to turn off the system versioning to enable this.<\/p>\n\n\n\n<p>So, this request would be to give us tables that are the <em>same<\/em> as the current temporal tables but, instead of everything being automated, let the user specify the end start and\/or end ones in the insert\/update. Then, let the user be able to update the history in a relatively simple manner. My preference would be to leave it to <em>us<\/em> to write the code ourselves!<\/p>\n\n\n\n<p>Here&#8217;s a couple of ways it could work:<\/p>\n\n\n<div class=\"block-core-list\">\n<ul class=\"wp-block-list\">\n<li>Instead of the columns in the <code>PERIOD FOR SYSTEM_TIME<\/code> setting being <strong>read only<\/strong>, allow you to send in the start time, and the rest be handled by your code.<br><br><\/li>\n\n\n\n<li>Allow the history table to be modified by the user, with the only constraint being no overlaps. See <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/5-t-sql-features-that-should-already-exist-2026-sql-server-wish-list\/\" target=\"_blank\" rel=\"noreferrer noopener\">Ed Pollack&#8217;s post<\/a> for how this could be done!<\/li>\n<\/ul>\n<\/div>\n\n\n<p>At this point, the table is basically just a <a href=\"https:\/\/coalesce.io\/data-insights\/type-1-vs-type-2-slowly-changing-dimensions\/\" target=\"_blank\" rel=\"noreferrer noopener\">Type 2 dimension<\/a> that lets us use the amazing syntax and be able to query our price structures. Even better, why not let the user pre-load future data into the so-called &#8220;history table&#8221;? <\/p>\n\n\n\n<p>Then, you could load up discounts (<em>and<\/em> get the current discount for a future order) using a construct similar to <code>FOR SYSTEM TIME (FOR USER TIME?)<\/code> &#8211; a construct that makes system versioned tables so very useful.<\/p>\n\n\n\n<section id=\"my-first-block-block_88b785311bdcf1966be82f3bbe41136b\" class=\"my-first-block alignwide\">\n    <div class=\"bg-brand-600 text-base-white py-5xl px-4xl rounded-sm bg-gradient-to-r from-brand-600 to-brand-500 red\">\n        <div class=\"gap-4xl items-start md:items-center flex flex-col md:flex-row justify-between\">\n            <div class=\"flex-1 col-span-10 lg:col-span-7\">\n                <h3 class=\"mt-0 font-display mb-2 text-display-sm\">Fast, reliable and consistent SQL Server development&#8230;<\/h3>\n                <div class=\"child:last-of-type:mb-0\">\n                                            &#8230;with SQL Toolbelt Essentials. 10 ingeniously simple tools for accelerating development, reducing risk, and standardizing workflows.                                    <\/div>\n            <\/div>\n                                            <a href=\"https:\/\/www.red-gate.com\/products\/sql-toolbelt-essentials\/\" class=\"btn btn--secondary btn--lg\" aria-label=\"Learn more &amp; try for free: Fast, reliable and consistent SQL Server development...\">Learn more &amp; try for free<\/a>\n                    <\/div>\n    <\/div>\n<\/section>\n\n\n<h2 class=\"wp-block-heading\" id=\"h-true-domains-in-sql-server\"><em>True<\/em> domains in SQL Server<\/h2>\n\n\n\n<p>For as long as I can remember, we could create a type in SQL Server such as:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">CREATE TYPE dbo.PhoneNumber FROM VARCHAR(12) NOT NULL;<\/pre><\/div>\n\n\n\n<p>This creates an alias of <code>VARCHAR(20)<\/code> that is <code>NOT NULL<\/code> in a column declaration <em>unless<\/em> you specify <code>NULL<\/code>, regardless of your <a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/t-sql\/statements\/set-ansi-null-dflt-on-transact-sql?view=sql-server-ver17\" target=\"_blank\" rel=\"noreferrer noopener\"><code>SET ANSI_NULL_DFLT_ON<\/code><\/a> setting.<\/p>\n\n\n\n<p>Then you can use it in a table create as:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">CREATE TABLE dbo.Customer\n(\n&nbsp;&nbsp;&nbsp; customer_id INT PRIMARY KEY,\n&nbsp;&nbsp;&nbsp; phone_number dbo.PhoneNumber\n);<\/pre><\/div>\n\n\n\n<p>The problem is, what about when I do this?<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">DECLARE @phone_number dbo.PhoneNumber;<\/pre><\/div>\n\n\n\n<p>Can this value be <code>NULL<\/code>? Yes, it can. But what if I want to make sure any value is inserted into a column or variable declared with the <code>dbo.PhoneNumber<\/code> type conformed to a certain nullability and format? &nbsp;<\/p>\n\n\n\n<p>For a column, this currently has to be done in a <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/theory-and-design\/the-check-constraint\/\" target=\"_blank\" rel=\"noreferrer noopener\"><code>CHECK<\/code> constraint<\/a> on any column that you want to enforce the format. Variables just have to repeat that format in code. This is tedious and error prone.<\/p>\n\n\n\n<p><em>NOTE: There is a long-deprecated method of attaching a check constraint to a <code>TYPE<\/code>, but it still didn\u2019t work on variables.<\/em><\/p>\n\n\n\n<p>So, I would love to be able to do something like the following:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">CREATE TYPE dbo.PhoneNumber FROM VARCHAR(20) NOT NULL\n     CHECK (REGEXP_LIKE(PhoneNmber, '^[0-9]{3}-[0-9]{3}-[0-9]{4}$');<\/pre><\/div>\n\n\n\n<p>And then when I type&#8230;<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">DECLARE @phone_number dbo.PhoneNumber = \u20181111111111\u2019;<\/pre><\/div>\n\n\n\n<p>&#8230;or&#8230;<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">DECLARE @phone_number dbo.PhoneNumber;<\/pre><\/div>\n\n\n\n<p>&#8230;both will immediately fail. The first is for a violation of the <code>CHECK<\/code> expression, and the second is simply because <code>NULL<\/code> values aren&#8217;t allowed. This would make such structures very valuable for important validations.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-a-big-sql-server-graph-enhancement-or-two\">A big SQL Server graph enhancement&#8230;or two<\/h2>\n\n\n\n<p>I understand that graphs in SQL Server are no longer high on the priority list for being updated. However, they&#8217;re supremely useful for modeling complex structures in a SQL database when you truly need it along with your relational data.<\/p>\n\n\n\n<p>For example, you may be implementing a <a href=\"https:\/\/www.salesforce.com\/uk\/crm\/what-is-crm\/\" target=\"_blank\" rel=\"noreferrer noopener\">customer management system (CRM)<\/a>. You need the ability to connect a customer to other customers, accounts, sales, etc. This will give you crucial information about customer influence so you can see how the salesperson made that big sale.<\/p>\n\n\n\n<p>You can model it as something like this:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">GenericConnectionId INT,\nGenericConnectionId_RelatedObjectName NVARCHAR(128)<\/pre><\/div>\n\n\n\n<p><em><strong>Note:<\/strong> this simple method assumes all structures in the same schema. The object could be identified with the <code>object_id<\/code> instead, but that is even more annoying to work with!<\/em><\/p>\n\n\n\n<p>From my experience with using a design like this, it&#8217;s very annoying to query beyond all imagination. Enter SQL Server\u2019s graph structures. They allow you to keep these details <em>in<\/em> the relationship so you can fan out connections between objects using a (slightly unpleasant) syntax.<\/p>\n\n\n\n<p>What I mean by &#8216;slightly unpleasant&#8217; is that it&#8217;s not as obvious as most T-SQL. It does work quite well to allow you to see multiple types of data in one query, but this takes a bit of configuration.<\/p>\n\n\n\n<p>That&#8217;s where the following feature suggestions come in. These additions could lead to graph types needing less and less code &#8211; code that <em>doesn\u2019t<\/em> use the graph features in a natural manner. After all, writing <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/t-sql-programming-sql-server\/sql-server-cte-basics\/#creating-a-recursive-sql-server-common-table-expression:~:text=has%20been%20defined.-,Creating%20a%20Recursive%20SQL%20Server%20Common%20Table%20Expression,-A%20recursive%20CTE\" target=\"_blank\" rel=\"noreferrer noopener\">recursive CTEs (common table expressions)<\/a> &#8211; or even just looping code &#8211; is quite tedious.<\/p>\n\n\n\n<p>Here are the three features I have in mind:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-filtered-shortest-path\">Filtered shortest path<\/h3>\n\n\n\n<p><a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/t-sql-programming-sql-server\/sql-server-2019-graph-database-and-shortest_path\/\" target=\"_blank\" rel=\"noreferrer noopener\"><code>SHORTEST_PATH<\/code> was a great improvement in SQL Server 2019<\/a>, making graph objects a rather decent tool for <em>some<\/em> applications. The problem is, you often want to find a path that isn\u2019t simply just the shortest through all nodes. <\/p>\n\n\n\n<p>So, my suggestion is a simple filter on the <code>SHORTEST_PATH<\/code> calculation to filter out (or in) certain nodes in the path. This would allow you to ask for the shortest path from Customer 1 to Customer 10 through, or not through, a certain sales order, customer, or any node that has edges between them.<\/p>\n\n\n\n<p>Bonus points might be to allow some ordering to the nodes be required, like from Customer 1 through Sales Order X and Customer Y, but not in the reverse order. This is far less necessary, of course.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-weighted-path\">Weighted path<\/h3>\n\n\n\n<p>Probably the feature that would be most exciting is the ability to do a weighted path. The idea here is that nodes have a cost or value associated with them. Orders might have a cost, distance between nodes, etc. So, instead of calculating the shortest path based on the number of edges between two nodes, each edge has a value that you need to add up to see what the overall cost is.<\/p>\n\n\n\n<p>For example, using a graph structure for booking flights. If you have all the routes you can get from one city to another, you can currently find the most direct flights from city to city using the <code>SHORTEST_PATH<\/code> syntax. But what about if there are two direct flights &#8211; or another with two options on top of that?<\/p>\n\n\n\n<p>Elsewhere, using our CRM example from before, you might want to find the connection between Customer 1 and Customer 10 through the &#8220;best&#8221; customer in total. This even comes into play when comparing two paths of the same length. <\/p>\n\n\n\n<p>Say Customer 1 and 10 both know Customer 3 and 4. 3 has never purchased anything, but 4 has. As <code>SHORTEST_PATH<\/code> works now, either node would satisfy the shortest path &#8211; not necessarily the most desirable.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-all-paths\">All paths<\/h3>\n\n\n\n<p>Finally, just allowing us to see every path in the output would be huge. OK, most of the time we just want to see that a node connects to a node <em>at all<\/em> &#8211; but the more you can see all the paths, the better. Plus, you can also do some of the things mentioned in the other two items yourself.<\/p>\n\n\n\n<p>This, of course, could be quite a costly operation. The feature would therefore need to be limited in the sense of just how far and wide it could work.<\/p>\n\n\n\n<p>However, of the three, it could be the most useful &#8211; with the caveat that you couldn\u2019t try to process a large set of data. Like trying to calculate the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Six_degrees_of_separation\" target=\"_blank\" rel=\"noreferrer noopener\">Six Degrees of Separation<\/a> from someone you know who is in <a href=\"https:\/\/www.imdb.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">IMDB<\/a> to Kevin Bacon.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-strict-compilation-mode-in-sql-server\">Strict compilation mode in SQL Server<\/h2>\n\n\n\n<p>The addition of a strict compilation mode to SQL Server is a common request (also see <a href=\"https:\/\/www.sommarskog.se\/wishlist.html#strictchecks\" target=\"_blank\" rel=\"noreferrer noopener\">Erland\u2019s list<\/a>.) T-SQL is not a <a href=\"https:\/\/www.freecodecamp.org\/news\/compiled-versus-interpreted-languages\/\" target=\"_blank\" rel=\"noreferrer noopener\">compiled programming language &#8211; rather it is interpreted<\/a> &#8211; so the code is very &#8220;loose&#8221;.<\/p>\n\n\n\n<p>There are plenty of benefits to &#8220;loose&#8221; code &#8211; you can even create the code without the table yet existing. And, in some cases, you may be using a table created <em>before<\/em> your code executes and is then dropped. <\/p>\n\n\n\n<p>However, I don\u2019t think anyone wants this to be a requirement for writing T-SQL. Due to object linking &#8211; which happens when you execute your code &#8211; it would greatly complicate managing SQL Server objects.<\/p>\n\n\n\n<p>So, for example, if you write this statement&#8230;<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">SELECT column_name \nFROM dbo.table_name;<\/pre><\/div>\n\n\n\n<p>&#8230;and then execute it, it will be parsed, verified, and only at that point will it check to see if <code>table_name<\/code> <em>actually exists<\/em>. This isn&#8217;t really noticeable when executing an ad-hoc statement, because it&#8217;s instantaneous.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-what-about-when-you-create-a-stored-procedure\">What about when you create a stored procedure?<\/h3>\n\n\n\n<p>However, when you create a <a href=\"https:\/\/www.red-gate.com\/simple-talk\/other\/for-the-love-of-stored-procedures\/\" target=\"_blank\" rel=\"noreferrer noopener\">stored procedure<\/a>&#8230;this is when it gets kind of weird at times. You can create either of the following objects on any SQL Server database where you have right to create a procedure\/<a href=\"https:\/\/www.geeksforgeeks.org\/sql\/scalar-function-in-sql-server\/\" target=\"_blank\" rel=\"noreferrer noopener\">scalar<\/a> function&#8230;<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">CREATE PROCEDURE dbo.procedure_name\nAS\nSELECT column_name \nFROM   dbo.table_name;\nGO<\/pre><\/div>\n\n\n\n<p>&#8230;or&#8230;<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">CREATE FUNCTION dbo.function_name\n()\nRETURNS int\nAS\nBEGIN\n    DECLARE @output int\n    SELECT @output = column_name \n    FROM   dbo.table_name;\n    RETURN @output;\nEND<\/pre><\/div>\n\n\n\n<p>Both of these will be <em>created<\/em> without error but, if you try to <em>use<\/em> either, you&#8217;ll receive an error that includes the following message (assuming you don\u2019t have a <code>table_name<\/code> object in your <code>dbo<\/code> schema with a column named <code>column_name<\/code>!):<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">Invalid object name 'dbo.table_name'.<\/pre><\/div>\n\n\n\n<p>However, when you try to create a <code>VIEW<\/code> object with the same code&#8230;<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">CREATE VIEW dbo.view_name\nAS\nSELECT column_name \nFROM   table_name;<\/pre><\/div>\n\n\n\n<p>&#8230;you immediately get this error:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">Msg 208, Level 16, State 1, Procedure view_name, Line 2 [Batch Start\nLine 0] Invalid object name 'table_name'.<\/pre><\/div>\n\n\n\n<p>My suggestion is for something like a setting, so you can be sure that all dependencies exist. Perhaps something like:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">SET STRICT DEPENDENCY CHECK ON<\/pre><\/div>\n\n\n\n<p>Now, the procedure or function creation would give the same failure <em>because I&#8217;ve asked it to<\/em>. Ironically, it <em>does<\/em> give you textual warnings when trying to use a non-existent procedure in a new stored procedure, but not one that causes failure. &nbsp;<\/p>\n\n\n\n<p>Again, handy when you&#8217;re trying to build your objects out of order. It&#8217;s less ideal, however, when you&#8217;re creating and deploying them, some object isn\u2019t there yet, and your object is created and doesn\u2019t complain at all.<\/p>\n\n\n\n<p>This one actually just caught me out on the day I finished writing this. I was creating a group of tables and stored procedures to use them but missed a table and the process failed. In DEV, of course&#8230;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-create-without-starting-a-new-batch-in-sql-server\"><code>CREATE<\/code> without starting a new batch in SQL Server<\/h2>\n\n\n\n<p>This is <em>not<\/em> one of the most important feature suggestions in this list. However, its absence does cause quite a bit of extra typing when you&#8217;re creating new objects.<\/p>\n\n\n\n<p>Some things, for example, require their own batch &#8211; leading you to write some code that just feels&#8230;<em>wrong<\/em>. For example, if you want to create a new stored procedure, you can\u2019t just write&#8230;<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">IF OBJECT_ID('new_procedure_name')\n BEGIN\n     CREATE PROCEDURE new_procedure_name\n     AS\n     SELECT 'hi';\n  END<\/pre><\/div>\n\n\n\n<p>&#8230;or you&#8217;ll receive the error <em>Incorrect syntax near the keyword \u2018PROCEDURE\u2019.<\/em> I get why this happens, in some cases, because <code>BEGIN<\/code> and <code>END<\/code> are not required, so they really couldn\u2019t know when it starts and stops.<\/p>\n\n\n\n<p>I don&#8217;t want them to make a huge breaking change and start this as a requirement, though. I&#8217;d just love for it to be resolved in some manner.<\/p>\n\n\n\n<p>It could be a new <code>BEGIN OBJECT<\/code>\u2026 <code>END OBJECT<\/code> syntax perhaps. There&#8217;s probably even something in the standards for this. <em>Without<\/em> this sort of syntax, however, extra code\/comments often end up in the procedure you&#8217;re writing.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-the-most-annoying-case-the-sql-server-create-schema-statement\">The most annoying case: the SQL Server <code>CREATE SCHEMA<\/code> statement <\/h3>\n\n\n\n<p>The <code>CREATE SCHEMA<\/code> statement is the one that is done the most, and it&#8217;s a far simpler syntax than any other version of this issue. This is because it&#8217;s quite often the one someone wants to create for a new schema to install some code. The fact that the statement needs to be in its <em>own<\/em> statement is a pain.<\/p>\n\n\n\n<p>Yes, I do know you can <a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/t-sql\/statements\/create-schema-transact-sql?view=sql-server-ver17#a-create-a-schema-and-granting-permissions\" target=\"_blank\" rel=\"noreferrer noopener\">create the schema and objects in one statement<\/a> but, even then, you can\u2019t <code>CREATE OR ALTER SCHEMA<\/code>. What I want to be able to do is just&#8230;<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">IF SCHEMA_ID('SchemaName') IS NULL \n     CREATE SCHEMA SchemaName;\n\nCREATE OR ALTER SchemaName.Procedure1 AS \n  BEGIN OBJECT \n     SELECT 'Hi' \n  END OBJECT;\n\nCREATE OR ALTER SchemaName.Procedure2 AS \n  BEGIN OBJECT \n     SELECT 'Hi2' \n  END OBJECT;<\/pre><\/div>\n\n\n\n<p>&#8230;all in the same batch.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-make-it-easier-to-use-extended-properties-in-sql-server\">Make it easier to use extended properties in SQL Server<\/h2>\n\n\n\n<p>I often use <a href=\"https:\/\/www.red-gate.com\/simple-talk\/devops\/database-devops\/reading-writing-creating-sql-server-extended-properties\/\" target=\"_blank\" rel=\"noreferrer noopener\">extended properties<\/a> in my SQL Server databases, mainly to document stuff that I&#8217;ve put into <a href=\"https:\/\/www.red-gate.com\/blog\/data-model-types\/\" target=\"_blank\" rel=\"noreferrer noopener\">data models<\/a>. It&#8217;s not easy, though. Even just generating code to create properties can be <em>really<\/em> painful.<\/p>\n\n\n\n<p>For example, to add a property to a column, you need to use the <a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/system-stored-procedures\/sp-addextendedproperty-transact-sql?view=sql-server-ver17#c-add-an-input-mask-property-to-a-column\" target=\"_blank\" rel=\"noreferrer noopener\">following syntax:<\/a><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">EXECUTE sp_addextendedproperty\n    @name = N'PropertyName', @value = 'Example',\n    @level0type = 'SCHEMA', @level0name = N'SchemaName',\n    @level1type = 'TABLE', @level1name = N'TableName',\n    @level2type = 'COLUMN', @level2name = N'ColumnName';<\/pre><\/div>\n\n\n\n<p>That is a <em>lot<\/em> of typing just to add a simple comment. I am not saying this loose hierarchy way of adding properties is <em>bad<\/em>. There&#8217;s just plenty of times where it would be nice to have a more typical one or two value addresses. Ones that are already pre-named for you.<\/p>\n\n\n\n<p>For example, maybe something like the following for all the basic object types&#8230;<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">EXECUTE sp_addobjectpropertyby @object_id INT, @name SYSNAME, @value \nVARIANT;<\/pre><\/div>\n\n\n\n<p>&#8230;and for their columns&#8230;<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">EXECUTE sp_addcolumnproperty @object_id INT, @column_id INT, @name \nSYSNAME, @value VARIANT;<\/pre><\/div>\n\n\n\n<p>And &#8211; while we&#8217;re at it &#8211; maybe a <code>COLUMN_ID<\/code> function that <em>works<\/em> like <code>OBJECT_ID<\/code>, but takes a qualified column name instead of an object? How about the same for an <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/learn\/sql-server-index-basics\/\" target=\"_blank\" rel=\"noreferrer noopener\">index<\/a>?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Easier dropping of dependencies<\/h2>\n\n\n\n<p>This is simple but would be really nice sometimes. I&#8217;m currently working on a project in <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/bi-sql-server\/what-is-microsoft-fabric-all-about\/\" target=\"_blank\" rel=\"noreferrer noopener\">Microsoft Fabric\u2019s<\/a> implementation of T-SQL where I&#8217;m generating lots of objects and code. Often, I just want to drop the schema and everything within it. I have scripts that can do this, of course, but if I could just type&#8230;<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">DROP SCHEMA SchemaName CASCADE;<\/pre><\/div>\n\n\n\n<p>&#8230;that would be awesome, especially when working with test databases. I could also see there being levels, like <code>CASCADE INTERNAL<\/code>, that would still fail on references <em>outside<\/em> of the schema. I don\u2019t see this happening anytime soon, though, as AI is making it easier and easier to write such code.<\/p>\n\n\n\n<p>The aforementioned script to do the cascading is something I just asked <a href=\"https:\/\/www.red-gate.com\/products\/sql-prompt\/\" target=\"_blank\" rel=\"noreferrer noopener\">SQL Prompt<\/a> to do. It spit out a set of queries to do the work for me. But while that is simple enough in an environment that I don\u2019t care much about, the script would need plenty of testing in a production or test setting before being used in a manual deployment.<\/p>\n\n\n\n<section id=\"my-first-block-block_f2901b1d196061a0b28d67fcdb67c965\" class=\"my-first-block alignwide\">\n    <div class=\"bg-brand-600 text-base-white py-5xl px-4xl rounded-sm bg-gradient-to-r from-brand-600 to-brand-500 red\">\n        <div class=\"gap-4xl items-start md:items-center flex flex-col md:flex-row justify-between\">\n            <div class=\"flex-1 col-span-10 lg:col-span-7\">\n                <h3 class=\"mt-0 font-display mb-2 text-display-sm\">Write accurate SQL faster in SSMS with SQL Prompt AI<\/h3>\n                <div class=\"child:last-of-type:mb-0\">\n                                            Write or modify queries using natural language, get clear explanations for unfamiliar code, and fix and optimize SQL with ease &#8211; all without leaving SSMS.                                    <\/div>\n            <\/div>\n                                            <a href=\"https:\/\/www.red-gate.com\/products\/sql-prompt\/#ai-powered-code\" class=\"btn btn--secondary btn--lg\" aria-label=\"Learn more and try for free: Write accurate SQL faster in SSMS with SQL Prompt AI\">Learn more and try for free<\/a>\n                    <\/div>\n    <\/div>\n<\/section>\n\n\n<h2 class=\"wp-block-heading\" id=\"h-autonomous-transactions-in-sql-server\">Autonomous transactions in SQL Server<\/h2>\n\n\n\n<p><strong>Autonomous transactions: another feature I&#8217;ve oft wanted to have a user-controlled version of in SQL Server. <\/strong><\/p>\n\n\n\n<p>As far as the user is concerned, when you execute <code>BEGIN TRANSACTION<\/code>, just one transaction has been started. You do have to execute <code>COMMIT TRANSACTION<\/code> once for every time you start a transaction but, if you want to undo that transaction, it just takes one <code>ROLLBACK TRANSACTION<\/code>.<\/p>\n\n\n\n<p>However, during your transaction\u2019s execution, there are a few things that aren\u2019t subject to that transaction. For example, <code>IDENTITY<\/code> values that are part of a rolled-back transaction are burnt and will not be reused.<\/p>\n\n\n\n<p><code>SEQUENCE<\/code> values are the same. While they have <em>some<\/em> form of transaction going on for consistency (so nobody gets the same value), they can\u2019t be rolled back; that would require other transactions to wait for their completion.<\/p>\n\n\n\n<p>Sometimes it would be wonderful to have that kind of power for our code, especially for error handling. Better still, imagine if you could start at least one transaction that we separate from the main transaction.&nbsp;Even if you could only do this for <em>one<\/em> statement, it would be an amazing improvement.<\/p>\n\n\n\n<p>Say, for example, you have this code&#8230;<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">BEGIN TRY\n BEGIN TRANSACTION;\n  INSERT INTO TableName(Column)\n  VALUES (NULL);\n COMMIT TRANSACTION;\nEND TRY;<\/pre><\/div>\n\n\n\n<p>&#8230;and now you want to write a <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/database-administration-sql-server\/handling-errors-in-sql-server-2012\/\" target=\"_blank\" rel=\"noreferrer noopener\"><code>CATCH<\/code> block<\/a> to log that error into your error table. Your transaction is in a <em>doomed<\/em> state when you reach the error handler. You can\u2019t just write the error log table and expect it to be there after you roll back.<\/p>\n\n\n\n<p>So ideally you could do something like the following (with more precision, transaction naming etc):<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">BEGIN CATCH\n  BEGIN AUTONONOMOUS TRANSACTION;\n    INSERT INTO ErrorLogTable(Message)\n    VALUES (@@ERROR_MESSAGE)\n  COMMIT AUTONOMOUS TRANSACTION;\n\n  ROLLBACK TRANSACTION;\n  THROW;\nEND CATCH;<\/pre><\/div>\n\n\n\n<p>Logging errors (and the like) would be one of the main uses for this feature, but there are others. Capturing values of parameters and columns, for example. And knowing when and where <code>AFTER<\/code> triggers, and identity and sequence values, have been generated. All of these would make troubleshooting so much easier.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-conclusion\">Conclusion<\/h2>\n\n\n\n<p>Ultimately, all of the SQL Server coding changes I&#8217;ve suggested in this article would be &#8220;nice to haves&#8221;. Some more so than others, but none are 100% essential &#8211; yet they would <em>all<\/em> make programmers\u2019 lives easier. And, as one such (relational) programmer, this is what I hope for.<\/p>\n\n\n\n<p>In summary, I hope to see:<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-better-internals\">Better internals&#8230;<\/h4>\n\n\n\n<p id=\"h-better-internalsand-the-less-we-relational-programmers-need-to-know-about-the-internals-the-better-because-that-is-the-ultimate-goal-you-write-a-query-send-it-to-the-engine-and-it-returns-you-an-answer-without-you-knowing-how\">&#8230;and the less we relational programmers need to know about the internals, the better! You write a query, send it to the engine, and it returns you an answer without you knowing how. <em>That<\/em> is the ultimate goal. <\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-better-administrative-tools\">Better administrative tools&#8230;<\/h4>\n\n\n\n<p id=\"h-better-administrative-toolsfrom-integration-to-security-high-availably-system-integration-etc-stuff-to-make-our-systems-just-plain-better\">&#8230;from integration to security, high availability, system integration, etc. Stuff to make our systems just plain better.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-t-sql-improvements\">T-SQL improvements&#8230;<\/h4>\n\n\n\n<p id=\"h-t-sql-improvements-keeping-up-with-other-data-platforms-and-beyond\">&#8230;keeping up with other data platforms and beyond&#8230;<\/p>\n\n\n\n<p>Finally, I&#8217;ll admit that my interest lies in T-SQL. It&#8217;s what I have done, and what I expect to do, until the day I put my keyboard out to pasture and only use a remote control.<\/p>\n\n\n\n<p>Some of my feature suggestions are bigger\/more complex than others, but they would all have a dramatic effect on how easy it is to use SQL Server &#8211; and thus the ultimate value it provides to the everyday user.<\/p>\n\n\n\n<section id=\"my-first-block-block_2e41039dda77690e7d902655a97d311f\" class=\"my-first-block alignwide\">\n    <div class=\"bg-brand-600 text-base-white py-5xl px-4xl rounded-sm bg-gradient-to-r from-brand-600 to-brand-500 red\">\n        <div class=\"gap-4xl items-start md:items-center flex flex-col md:flex-row justify-between\">\n            <div class=\"flex-1 col-span-10 lg:col-span-7\">\n                <h3 class=\"mt-0 font-display mb-2 text-display-sm\">Subscribe to the Simple Talk newsletter<\/h3>\n                <div class=\"child:last-of-type:mb-0\">\n                                            Get selected articles, event information, podcasts and other industry content delivered straight to your inbox.                                    <\/div>\n            <\/div>\n                                            <a href=\"https:\/\/www.red-gate.com\/simple-talk\/subscribe\/\" class=\"btn btn--secondary btn--lg\" aria-label=\"Subscribe now: Subscribe to the Simple Talk newsletter\">Subscribe now<\/a>\n                    <\/div>\n    <\/div>\n<\/section>","protected":false},"excerpt":{"rendered":"<p>A T-SQL veteran&#8217;s wish list: 9 missing SQL Server features that would simplify auditing, data validation, graph queries, and error handling.&hellip;<\/p>\n","protected":false},"author":56085,"featured_media":107820,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143523,53,143524,143531],"tags":[4168,4170,4150,4151,4252],"coauthors":[19684],"class_list":["post-111987","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-databases","category-featured","category-sql-server","category-t-sql-programming-sql-server","tag-database","tag-database-administration","tag-sql","tag-sql-server","tag-t-sql-programming"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/111987","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/56085"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=111987"}],"version-history":[{"count":5,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/111987\/revisions"}],"predecessor-version":[{"id":112003,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/111987\/revisions\/112003"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media\/107820"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=111987"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=111987"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=111987"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=111987"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}