Multiple SqlString actions at different sequences in Wix - sql-server

I'd like to execute SQL strings at two different sequences in the InstallExecuteSequence.
The problem is that it seems if you use the supplied <sql:SqlString \>, they get bundled into the 'InstallSqlData' action.
Is there a way to specify that certain SqlString elements get executed at a different stage (so that I can run a separate custom action in between)

I don't think that's possible.
You might think you could add a new CustomAction tag pointing to Wix's Sql CA and schedule it at a different point in the InstallExecuteSequence. Unfortunately, both instances of the CA will iterate over the same rows in the same tables, so the effect will be to execute each SqlString twice.

Related

SSIS - importing identical data from multiple databases

I want to copy and merge data from tables with identical structure (in a number of different source databases) to a single table of similar structure in a destination database. From time to time I need to add or remove a source database.
This is currently achieved using a Data Flow Task containing an OLEDB source with a SQL query within which there is a UNION for each of the databases I am extracting from. There is quite a lot of SQL within each UNION so, if I need to add fields, I need to add the same additional SQL to each UNION. Similarly, when I add or remove a source database I need to add or remove a UNION.
I was hoping that, rather than use such a UNION with a lot of duplicated code, I could, instead, use a Foreach Loop Container that executes SQL contained in a variable using parameters to substitute the name of the database and other database dependent items within the SQL on each iteration but I hit problems with that as I assume the Data Flow Task within the loop could not interpret the incoming fields because of the use what is effectively dynamic SQL.
Any suggestions as to how I might best achieve this without duplicating a lot of SQL?
It sounds like you have your loop figured out for moving from database to database. As long as the table schemas are identical (other than names as noted) from database to database, this should work for you.
Inside the For Each Loop container, create either a Script Task or an Execute SQL Task, whichever you're more comfortable working with.
Use that task to dynamically generate the SQL of your OLE DB Source query, changing the Customer Code prefix for each iteration. Assign the SQL text to a variable, either directly in a Script Task, or by assigning the Result Set of your Execute SQL Task (the result set being the query text) to a variable.
Inside your Data Flow Task, in the OLE DB Source, under Data Access Mode select "SQL Command from variable". Select the variable that you populated with your query in the last task.
You'll also need to handle changing the connection string between iterations, but, again, it sounds like you have a handle on that part already.

SQL Server extended events: write custom predicates?

We have about 2'000 "old" objects in a sql server database (tables, views etc.) of which we don't really know if they're still in use. I want to create an extended event listener for these objects. I tried to add a giant WHERE clause to the CREATE EVENT SESSION command, consisting of 2'000 [package0].[equal_int64]([object_id], (<objectId>)) statements.
However, the command max length is 3'000 characters, so I cannot do this. And I guess that the performance of this filer wouldn't be too good, anyway...
Now my question is: I can query all possible predicates using select * from sys.dm_xe_objects where object_type= 'pred_compare'. this gives me results such as name=equal_uint64, package_guid=60AA9FBF-673B-4553-B7ED-71DCA7F5E972. the package_guid refers to sys.dm_xe_packages, where several DLLs are referenced which seem to implement a particular predicate.
Would it be possible to define my own "package" and implement a predicate there (which would filter the objectId using a hashtable)? Is it possible somehow to import such a package into SQL server so I could define a custom predicate?
Or does anyone have another idea how to implement such a filter?

Better Way to Remove Special Characters - Access SQL

I'm looking for a way to remove special characters from a field within my Access database. The field has both text and numbers along with dashes, underscores and periods. I want to keep the letters and numbers but remove everything else. There are multiple examples of VB scripts, and some in SQL, but the SQL examples I've seen are very lengthy and do not seem very efficient.
Is there a better way to write a SQL script to remove these characters without having to list each of the special characters such as the below example?
SELECT REPLACE([PolicyID],'-','')
FROM RT_PastDue_Current;
If you are actually manipulating the data and executing code from the context of the MS Access application, then SQL calls can call any public function inside the modules in the MDB. You could write a cleanup function, then
UPDATE Mytable SET MyField=Cleanup(MyField)
Other than that, I have yet to encounter any RDBMS database engine that has much advanced string manipulation features beyond the simple Replace you've mentioned.

How can I stop MiniProfiler showing "duplicate" SQL query warnings parameters are different?

I'm using MiniProfiler to check what NPoco is doing with SQL Server but I've noticed it reports duplicate queries even when the SQL parameters have different values.
Eg: if I fetch a string from a database by ID, I might call:
SELECT * FROM PageContent WHERE ID=#ID
...twice on the same page, with two different IDs, but MiniProfiler reports this as a duplicate query even though the results will obviously be different each time.
Is there any way I can get MiniProfiler to consider the SQL parameter values so it doesn't think these queries are duplicated? I'm not sure if this problem is part of MiniProfiler or if it's a problem in how NPoco reports it's actions to MiniProfiler so I'll tag both.
I think that this is by design, and is in fact one of the reasons for the existence of the duplicate query detection.
If you are running that query twice on one page where the only difference is the param value, then you could also run it one time and include both param values in that query.
SELECT * FROM PageContent WHERE ID in (#ID1, #ID2)
So you are doing with two queries what you could do with one (you would have to of course filter on server side, but that is faster than two queries).
The duplicate query label is not for saying that you are running the absolute identical query more than once (though it would apply there as well). Rather it is highlighting an opportunity for optimizing your query approach and consolidating different queries into one (think about what an N+1 situation would look like).
If the default functionality doesn't meet your needs, you can always change it! The functionality that calculates duplicateTimings is located in UI/includes.js. You can provide your own version of this file that defines duplicates in a different way (perhaps by looking at parameter values in addition to the command text when detecting duplicates) by turning on CustomUITemplates inside MiniProfiler, and putting your own version of includes.js in there.

How do SQL parameters work internally?

A coworker and I were browsing SO when we came across a question about SQL Injection, and it got us wondering: how do parametrized queries work internally? Does the API you are using (assuming it supports parametrized queries) perform concatenation, combining the query with the parameters? Or do the parameters make it to the SQL engine separately from the query, and no concatenation is performed at all?
Google hasn't been very helpful, but maybe we haven't searched for the right thing.
The parameters make it to the SQL engine separately from the query. Execution plan calculated or reused for the parametrized query, and then query is executed by sql engine with parameters.
Paramters make it to the SQL server intact, and individually "packaged" with meta data indicating their type, whether Input or Output etc. As Alex Reitbort points out, it is so because the parametrized statements are a server level concept, not merely a convenient way of invoking commands from various connection layers.
I doubt that SQL SERVER builds a complete query string from the given parametrized query where the parameter list is concatenated in.
It most likely parses the given parametrized command string splitting it into an internal data structure based on reserved words and symbols (SELECT, FROM, ",", "+", etc). Within that data structure, there are properties/places for values like table names, literals, etc. It is here that it copies (verbatim) the each passed in parameter (from the list) into the proper section of that structure.
so your #UserName value of: 'x';delete from users --
in not never needs to be escaped, just used as the literal value it really is.
Parameters are passed along with the query (not within the query), and are automatically escaped by the API as they are sent in accordance with the underlying database communications protocol.
For example, you might have
Query: <<<<select * from users where username = :username>>>>
Param: <<<<:username text<<<<' or '1' = '1>>>>>>>>
That's not the exact encoding any database protocol actually uses, but you get the idea.

Resources