I am currently trying to clean up some stored procedures. There are about 20 of them that look very similar and do many of the same things, but take in slightly different parameters and filter data differently.
For the most part, all of the stored procs start by loading some data in to one or two table variables (which is generally where the procs differ). After that, all of the code for each sproc is more or less the same. They perform some logging and apply some additional common filters.
I wanted to at least turn the common pieces in to stored procs so that the code would be easier to read and we wouldn't have to open 20 procedures to update the same line of sql, but the use of table variables prevents it. We are using Sql Server 2005, and to my knowledge we cannot used table valued parameters in our stored procedures.
We could, however, change all of the table variables to temp tables and reference them in the new common stored procedures. I am assuming that is a fairly common practice, but wanted to know if it was actually a good idea.
In the nested stored procedures, should I assume that a temp table has already been created elsewhere and just query off of it? I can test whether or not the table exists, but what if it doesn't? Is there a good alternative to this in 2005? Is it confusing for other developers who open one of the nested stored procs and see a temp table that is created elsewhere? Do I just need to add lots of informative comments?
In your nested proc; to be sure, you can check whether table exist or not. If not exist then RAISERROR with some error message. Since, you are using SS2005, #temptable would be the option you have. Commenting your code for ease of readability is never a bad practice.
Talking about naming convention; follow any convention that fits better in your organization (I just gave a proper name to the SP that will reflect the purpose of the SP). If code changes is happening then changing the comment accordingly is the developer responsibility. Other than this, whatever you are doing looks correct to me.
Related
I'm trying to clear out a lot of clutter in various databases on a SQL Server that were left behind by some sloppy prior employees. My boss is afraid to let me delete unused tables because he believes it might not generate an error message, but might simply cause wrong data to be returned. I don't see how; if a table is joined in a SQL statement and the table doesn't exist, I can't imagine it not raising an error. Is this possible?
In normal circumstance you'd always get an error, however these may not be normal circumstances.
It's unlikely, but if you have procedures building dynamic SQL using the information_schema views to get table names you could potentially write some SQL that fails silently if the table isn't there
It's technically possible depending on how you access the data and how any stored procedures querying said table were written. E.g. if there are TRY CATCH blocks in your T-SQL, it could be possible. But that's just theoretical. In practice, you'll get real ugly errors if you delete a table.
What I would do in the interim is rename the table and then run every unit test and integration test you can find. If something references the table, rename it back to what it was, otherwise dump it.
Consider the following abstract situation (just as an example):
I have two tables TableA and TableB. They have unique IDs and possibly other columns (which are irrelevant) The relatioship between them is many to many so I have a third table AssociationTable that is used to store the relationships between them. Basically, AssociationTable will have two columns (ID_A and ID_B - foreign keys).
If I delete a row in AssociationTable and the ID_A that was deleted was the last one, I would also like to delete the entry from TableA that corresponds to that ID.
I could do this:
a) From the application that uses the database
b) by using an SQL trigger
My question, basically, is the following:
Is there any good practice that says "if you can do something from both the application and from SQL, always prefer sql." ?
Or does it depend on the case? If so, what should I take into account?
Performance: The query plan for stored procedures is compiled onn DB Server and subsequent requests can run faster.
A stored procedure can execute multiple steps and the intermediate results need not go back to application layer, reducing traffic between an application and the DB server.
Security: Stored procedures are well defined database objects that can be locked down with security measures. Use of typed parameters can help prevent SQL injection attacks.
Code re-use: SQL queries can be written once and re-used across multiple clients without writing the same SQL commands over and over again.
Abstraction: By putting all the SQL code into a stored procedure, the application is completely abstracted from the field names, tables names, etc. So when a SQL query needs to be changed, there is almost zero or NO impact in the application code.
There are more benefits of doing it in the database.
Other client application code need not worry about data integrity.
The data logic should remain as close to data as possible
It could be faster if managed by DB (trigger invocation).
I'm looking for a way to get all table creation and alteration queries attached to a database, in SQL Server 2000. Is this stored in a system table, or is there a built in method to remake them?
Goal: to extract the schema for customizable backups.
My research so far turned up nothing. My Google-Fu is weak...
Note that I don't know that there's a way to specify which filegroup a stored procedure is on (other than the default). So what you may consider, in order to at least keep the script repository backup small, is:
create a filegroup called non_data_objects, and make it the default (instead of PRIMARY).
create a filegroup for each set of tables, and create those tables there.
backup each set of tables by filegroup, and always include a backup of non_data_objects so that you have the current set of procedures, functions etc. that belong to those tables (even though you'll also get the others). Because 1. will only contain the metadata for non-data, it should be relatively small.
You might also consider just using a different database for each set of tables. Other than using three-part naming in your scripts that need to reference the different sets, there really is no performance difference. And this makes your backup/recovery plan much simpler.
I read about temporary tables, global temporary tables and table variables. I understood it but could not imagine a condition when I have to use this. Please elaborate on when I should use the temporary table.
Most common scenario for using temporary tables is from within a stored procedure.
If there is logic inside a stored procedure which involves manipulation of data that cannot be done within a single query, then in such cases, the output of one query / intermediate results can be stored in a temporary table which then participates in further manipulation via joins etc to achieve the final result.
One common scenario in using temporary tables is to store the results of a SELECT INTO statement
The table variable is relatively new (introduced in SQL Server 2005 - as far as i can remember ) can be used instead of the temp table in most cases. Some differences between the two are discussed here
In a lot of cases, especially in OLTP applications, usage of temporary tables within your procedures means that you MAY possibly have business processing logic in your database and might be a consideration for you to re-look your design - especially in case of n tier systems having a separate business layer in their application.
The main difference between the three is a matter of lifetime and scope.
By a global table, I am assuming you mean a standard, run of the mill, table. Tables are used for storing persistent data. They are accessible to all logged in users. Any changes you make are visible to other users and vice versa.
A temporary table exist solely for storing data within a session. The best time to use temporary tables are when you need to store information within SQL server for use over a number of SQL transactions. Like a normal table, you'll create it, interact with it (insert/update/delete) and when you are done, you'll drop it. There are two differences between a table and a temporary table.
The temporary table is only visible to you. Even if someone else creates a temporary table with the same name, no one else will be able to see or affect your temporary table.
The temporary table exists for as long as you are logged in, unless you explicitly drop it. If you log out or are disconnected SQL Server will automatically clean it up for you. This also means the data is not persistent. If you create a temporary table in one session and log out, it will not be there when you log back in.
A table variable works like any variable within SQL Server. This is used for storing data for use in a single transaction. This is a relatively new feature of TSQL and is generally used for passing data between procedures - like passing an array. There are three differences between a table and a table variable.
Like a temporary table, it is only visible to you.
Because it is a variable, it can be passed around between stored procedures.
The temporary table only exists within the current transaction. Once SQL Server finishes a transaction (with the GO or END TRANSACTION statements) or it goes out of scope, it will be deallocated.
I personally avoid using temporary tables and table variables, for a few reasons. First, the syntax for them is Microsoft specific. If your program is going to interact with more than one RDBMS, don't use them. Also, temporary tables and table variables have a tendency to increase the complexity of some SQL queries. If your code can be accomplished using a simpler method, I'd recommend going with simple.
I have an assortment of database objects (tables, functions, views, stored procedures) each scripted into its own file (constraints are in the same file as the table they alter) that I'd like to be able execute in an arbitrary order. Is this possible in SQL Server 2005?
Some objects as an example:
Table A (references Table B)
Table B (references Function A)
Function A (references View A)
View A (references Table C)
Must be run in the following order:
Table C
View A
Function A
Table B
Table A
If the scripts are run out of order, errors about the missing objects are thrown.
The reason I ask is that in a project I'm working on we maintain each database object in its own file (for source control purposes), and then maintain a master script that creates each database object in the correct order. This requires the master script to be manually edited any time an object is added to the schema. I'd like to be able to just execute each script as it is found in the file system.
In my experience the most problematic issue is with views, which can reference recursively. I once wrote a utility to iterate through the scripts until the errors were all resolved. Which only works when you're loading everything. Order was important - I think I did UDTs, tables, FKs, views (iteratively), SPs and UDFs (iteratively until we decided that SPs calling SPs was a bad idea, and UDFs are generally a bad idea.)
If you script the foreign keys into separate files, you can get rid of table-table dependencies, if you run the FK script after creating all tables.
As far as I'm aware, functions and procedures check for object existence only in JOIN clauses.
The only difficulty I found was views depending on views, as a view definition requires that the objects the view depends on do exist.
I found this page where the author has written a nice procedure for doing exactly what you are talking about. Sounds like you just need to have two versions of it, one for disabling the constraints and another to re-enable then.
APEX SQL Script is supposed to analyze the dependencies and order the script appropriately, but even then I've had problems.