a simple way to generate SQL Server's “standard” form of an expression?

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-05 17:57:27

I will also add, that "normalization" of expression sometimes do not only adds brackets, but it also changes some expressions in a very different way!

For example in MS SQL 2008 Express I created a default with the following expression:

year(getdate()) + 1

but SQL Server changes it to be

(datepart(year,getdate())+(1))

So, I don't believe that any kind of rules or regular expressions will solve your problem for 100% of cases, so I do recommend you to combine several methods

1) First of all I think that in your case there is a limited number of typical constraints, that usually exists in most databases. As a rule, there are getdate(), and constant numeric expressions (0), (1). You can have a table of those typical constraints that will help you to match expected and real expressions.

2) Then you can try very simple rule to include all fields names in [] brackets and all constants and math operations in (), so you will have year + 1 transformed into ([year] + (1)). I suppose this could be done with a Regular Expressions.

3) for all cases where you was not able to compare expected and actual results using 1th or 2nd method, you will do what you suggested - create a temp table and compare results.


EDIT 04.Aug:

I found that when you create a database-level defaults, they will not be normalized. Strange, eh? But probably, you can use this fact and create database-level defaults that you bind to columns instead of creating default constraints for columns (though, I suppose this will be a very big change in design and will require a huge update of existing databases)

As for columns default constraints, and the approach to create/drop defaults dynamically in order to get their normalized form, here is a simple C# code using Microsoft.SqlServer.Management.Smo library. I will suggest to create one test_table with columns IntTest int, VarcharTest varchar(1), DateTimeTest datetime and so on - i.e. only one column for each type. In this case you will create/drop defaults but will not have to create drop table and columns and this will increase the performance.

C# code will follow (include using Microsoft.SqlServer.Management.Smo;)

        Server server = new Server("localhost\\SQLEXPRESS");
        Database db = server.Databases["test"];
        Table t = db.Tables["test_defaults"];
        //here should be some logic to select column name depending on default data type
        //for example for DateTime defaults we will use "DateTimeTest" column
        Column c = t.Columns["DateTimeTest"];

        //clean up previous results if they exist
        DefaultConstraint constr = c.DefaultConstraint;
        if (constr != null) constr.Drop();

        //create new constraint
        constr = c.AddDefaultConstraint();
        constr.Text = "getdate()";
        constr.Create();
        //after refresh we will have a new text
        constr.Refresh();
        string result = constr.Text;

        //drop it if we don't need it
        constr.Drop();

I feel like there should be answer by connecting to the DAC (so that you can query the system tables), but I can't actually find out how the function 'object_definition' works.

This may be a question for someone like Kalen Delaney, to find out if there's a public function that these things get parsed with.

Rob

I'd lean towards your third solution (create a table with that constraint and read it back) - you can do it with a temp table, so it would be semi-clean, and if you cache the normalized form, you'd only need to do it when what you're searching for changes. I'm not sure how static the expressions you're searching for are, but when they change, just have part of the save process be that it creates a temp table, applies the constraint, reads it from the definition, and saves it along with the native form of the constraint.

If this isn't what you're looking for (besides that it's not completely clean), let me know and I can adjust it as needed.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!