Qualified naming - tsql

I'm currently doing some maintenance on an application and I've come across a big issue regarding the qualified name in tsql. I wondering if someone could clear my confusion up for me.
From my understanding you want to use USE [DatabaseName] to declare which database you are using. I notice if u "rename" the databse it automatically updates these references in your code.
However, the developer who originally wrote this code used the USE [DatabaseName]. Then in later statements he wrote: SELECT * FROM [DatabaseName].[dbo].[Table]. Well this obviously breaks if I change the Database's name. From what i've read you want to qualify names only to the owner such as: [dbo].[TableName] so it knows where to look which increases performance.
Is there a reason he included the Database name in each statement?

From what i've read you want to qualify names only to the owner such as: [dbo].[TableName] so it knows where to look which increases performance.
Not that I'm aware of, rather it looks like someone is lazy.
I always use the three name format (unless accessing a linked server instance, then it's four).
The benefit is that the correct table from the correct database & schema will be used without concern for an errant USE [appropriate database] statement. As long as the object exists, and the permissions are valid based on the need, you can recreate a stored procedure, function, view, etc in other databases without needing to address the USE [appropriate database] statement each time.
But I'm working with data spread over numerous databases on the same instance. I wouldn't have necessarily designed it that way, but it wouldn't change that I use three (or four) part qualified name format.

Related

How do I specify the User-Defined Table Type for a property with Insight Database

I have a pretty simple stored procedure to just update the status value for a bunch of records. I send in an unknown value of record IDs and it works.
I love using Insight.Database and wouldn't want to use anything else if possible.
The problem is our DBA's created multiple User-Defined Table Types to handle situations. But their naming conventions are identical.
We have a [IntTable] with column [IntValue]
and another [TinyIntTable] with column [TinyIntValue]
Insight appears to inspect the type of UDT that could work. And sometimes it chooses [TinyIntTable] (I am guessing because the values in the array being sent are all small enough to fit into a tinyInt. But that [TinyIntTable] isn't compatible with the stored procedure. How do I force Insight.Database to always use the [IntTable]?
Is there an attribute I could use on my c# object definition?
If you’re using stored procedures, then insight will check the type of the parameter and use the correct one. i.e. it should just work.
So your problem is likely something else. Check out the table type section on the wiki, and if that doesn’t solve it for you, please post a simple example on github and we’ll help you out.

Is it possible to prevent the reading and/or setting of a field value with DBIx Class?

I'm working in a project that uses Catalyst and DBIx::Class.
I have a requirement where, under a certain condition, users should not be able to read or set a specific field in a table (e.g. the last_name field in a list of users that will be presented and may be edited by the user).
Instead of applying the conditional logic to each part of the project where that table field is read or set, risking old or new cases where the logic is missed, is it possible to implement the logic directly in the DBIx::Class based module, to never return or change the value of that field when the condition is met?
I've been trying to find the answer, and I'm still reading, but I'm somewhat new to DBIx::Class and its documentation. Any help would be highly appreciated. Thank you!
I‘d use an around Moose method modifier on the column accessor generated by DBIC.
This won‘t be a real security solution as you can still access data without the Result class, for example when using HashRefInflator.
Same for calling get_column.
Real security would be at the database level with column level security and not allowing the database user used by the application to fetch that field.
Another solution I can think of is an additional Result class for that table that doesn‘t include the column, maybe even defaulting to it and only use the one including the column when the user has a special role.

Is it safe to use fundamental type OID defined in catalog header on client code?

This QA entry shows how to get OID code from catalog header.
It might be the simplest way to get OID numbers. Anyway the header file itself is explicitly separated from client-side header, so it seems it implies not to be used on client side.
Is it safe to use these server-side constants on client side? It's predictable that it will make some legacy issue. Older version of server may lack specific OID code. So I ask excluding this case. I mean, can I assume *once define OID code for fundamental types to be same eternally on future versions*?
Update
I meant only for fundamental types. Such as TEXTOID, INT8OID or TIMESTAMPOID. No custom, composite, user-defined or any other non-fundamental stuffs.
Currently, this is the best I could find. I would go with hardcoding OIDs.
Cited from Merlin Moncure's mention from the mailing list entry.
built in type oids are defined in pg_type.h: cat
src/include/catalog/pg_type.h | grep OID | grep define
built in type oids don't change. you can pretty much copy/pasto the
output of above into an app...just watch out for some types that may
not be in older versions.
user defined type oids (tables, views, composite types, enums, and
domains) have an oid generated when it is created. since that oid can
change via ddl so you should look it up by name at appropriate times.
Is it safe to use these server-side constants on client side? (...) I mean, can I assume once define OID code to be same eternally on future versions?
I honestly doubt it's not safe. The oids will likely be different depending on the Postgres version that was initially installed when new types etc are introduced. Older installs that get upgraded may or may not have the same oids as the same on fresh installs.
For illustration purposes, picture yourself creating an admin user with ID 1 in an app when it gets installed, and hard-coding everything in C by defining ADMIN_USER as that ID. Your customers then add new users, etc. In a subsequent release, you add a quasi-admin user with ID 2 and proceed tohard-code everything around that too. Customers upgrade... and, well, it blows up in your face because on their end, the quasi-admin user can have any ID...
When you use hard-coded oids in Postgres, the same kind of thing may happen. In one version, the built-in types are created in a certain order; in the next, they may be created in another because e.g. Postgres adds a shiny new enum or int4range type. And this doesn't begin to touch the topic of what may potentially occur during upgrades. (Admittedly, dumping and reloading data should yield sane things here, but I wouldn't take the chance myself.)

Is it possible to create permanent object aliases

I recently found myself using some rather lengthy names for the tables and views involved in a development piece, which got me wondering whether it's possible to create client/database/server level aliases for objects.
Say for example I have a view named dbo.vAlphaBetaGammaDelta . Is there a way (with or without Intellisense) to create a reference to it named dbo.vABGD ?
If not, would there be any downfalls to creating a view of a view or single table aside from maintenance necessary if/when the table schema changes?
I should note that these aliases/views would not be intended for use in other objects, but for alleviation and prevention of carpal tunnel during day-to-day troubleshooting and delving xD
SQL Server allows for the creation of synonyms. That seems to be what you are looking for: http://msdn.microsoft.com/en-us/library/ms177544.aspx
However, as #MitchWheat mentioned. this seems to be going in the wrong direction. There are a few quite good SSMS plugins available that provide auto completion of long object names (e.g. SQL Prompt). Incidentally those products have trouble with synonyms...
There are many cases where you would like to have synonyms.
Let me state just one for start:
You have a well defined hypothetical name of a table: GlobalStatisticalRecord. Hundreds of lines of code and objects (keys, indexes, etc.) in SQL and elsewhere are referring to this table name.
After 5 years of usage, the abbreviation GSR was accustomed not only among the technical people, but also among the business users. So, to stress again, GSR is now even more recognizable than GlobalStatisticalRecord. However, for the new people that come into the technical team, it is good to keep the name GlobalStatisticalRecord as a table name, since it nicely describes what is the table all about. Now, when writing a quick adhoc query - and that may not be from your tool of choice with all the Intellisense features you are accustom to - then these aliases are really saving your time (and "life" at 2am in the morning when you are frantically trying to diagnose a production problem).
Please, if you never faced a case when you would need this, just don't assume that there is none.
I stressed the adhoc adjective, since I agree that in permanent queries (stored procedures, etc.), for the reasons you pointed out, it is advisable to use the full table names.

variable table or column names in a function

I'm trying to search all tables and columns in a database, a la here. The suggested technique is to construct SQL query strings and then EXEC them. This works well, as a stored procedure. (Another example of variable table/column names is here. Again, EXEC is used to execute "dynamic SQL".)
However, my app requires that I do this in a function, not an SP. (Our development framework has trouble obtaining results from an SP.) But in a function, at least on SQL Server 2008 R2, you can't use EXEC; I get this error:
Invalid use of a side-effecting operator 'INSERT EXEC' within a function.
According to the answer to this post, apparently by a Microsoft developer, this is by design; it has nothing to do with the INSERT, only the fact that when you execute dynamically-constructed SQL code, the parser cannot guarantee a lack of side effects. Therefore it won't allow you to create such a function.
So... is there any way to iterate over many tables/columns within a function?
I see from BOL that
The following statements are valid in a function: ...
EXECUTE
statements calling extended stored procedures.
Huh - How could extended SP's be guaranteed side-effect free?
But that doesn't help me anyway:
The extended stored procedure, when it is called from inside a
function, cannot return result sets to the client. Any ODS APIs that
return result sets to the client will return FAIL. The extended stored
procedure could connect back to an instance of SQL Server; however, it
should not try to join the same transaction as the function that
invoked the extended stored procedure.
Since we need the function to return the results of the search, an ESP won't help.
I don't really want to get into extended SP's anyway: incrementing the number of programming languages in the environment would complicate our development environment more than it's worth.
I can think of a few solutions right now, none of which is very satisfactory:
First call an SP that produces the needed data and puts it in a table, then select from the function which merely reads the result from the table; this could be trouble if the search takes a while and two users' searches overlap. Or,
Have the application (not the function) generate a long query naming every table and column name from the db. I wonder if the JDBC driver can handle a query that long. Or,
Have the application (not the function) generate a long series of short queries naming every table and column name from the db. This will make the overall search a lot slower.
Thanks for any suggestions.
P.S. Upon further searching, I stumbled across this question which is closely related. It has no answers.
Update: No longer needed
I think this question is still valid, and we may again have a situation where we need it. However, I don't need an answer anymore for the present problem. After much trial-and-error I managed to get our application framework to retrieve row results from the RDBMS via the JDBC driver from the stored procedure. Therefore getting the thing to work as a function is unnecessary.
But if anyone posts an answer here that helps with the stated problem, I will be happy to upvote and/or accept it as appropriate.
An sp is basically a predefined sql statment with some add ons.
So if you had
PSEUDOCODE
Create SP_DoSomething As
Select * From MyTable
END
And you can't use the SP
Then you just execute the SQL as in "Select * From MyTable"
As for that naff sql code.
For start you could join table to column with a where clause, which would get rid of that line by line if stuff.
Ask another question. Like How could this be improved, there's lots of scope for more attempts than mine.