Running a basic select on SQL Sever asks for column name that doesn't exist, why? - sql

We had another developer come through and complete some work for us. Unfortunately he didn’t work well within our team and management let him go.
Because of this now I’m stuck debugging his code and undoing work that was done. He did not document his code (one of the reasons he was let go), rarely notating anything, therefore I have no idea where to begin looking.
When I run a basic SELECT on two specific tables in our DB:
SELECT * FROM table_name
Using SQL Server Management Studio I get this...
Msg 207, Level 16, State 1, Line 1
Invalid column name 'eventTime'.
There was an eventTime column but wasn’t necessary and wasn't being used in any PHP file, however it seems somehow directly tied to the table now and I have no idea where to look to find it. The error message provided is pointing to my SELECT statement, but there is nothing wrong with it, nor does it even reference the eventTime column.
I’ve looked and there don’t seem to be any triggers or stored procedures referencing this table. Is there another way I can try to track this down?

This sounds like a hard'ish problem. Here are some ideas.
My first thought is that table_name is a view, and somehow the view has gotten out-of-sync with the underlying table definitions. I have seen problems with types in some circumstances. I imagine the same could happen with column names.
The next thought is that table_name has computed columns. In this case, the computed columns could be using a function and the function call could be generating the error. I cannot think of any other way to run code with a simple select.
I don't think the problem would be a foreign key constraint unless. So, a third option is that a foreign key constraint is referencing a table in the same database but a different schema. The different schema could have permissions that make the table inaccessible.
For any of these, scripting out the definition in SSMS will help you fix the problem.

Related

Can a missing table cause no error?

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.

SQL - Table not found after backup

I saved a SQL table before deleting some information from it with the sql statment:
select * into x_table from y_table
After doing some operations, I want to get back some information from the table I saved with the query above. Unfortunately, MS SQL Server MGMTS shows an error saying that the table does not exist.
However, when I put the drop statement, the table is recognized - and the table is not underlined.
Any idea why this table is recognized by the drop table statement and not the select from statement. This seems strange for me.
EDIT:
Thank you
It may be that the table isn't underlined in your drop table command because its name is still in your IntelliSense cache. Select Edit -> IntelliSense -> Refresh Local Cache in SSMS (or just press Ctrl+Shift+R) and see if the table name is underlined then.
Edit:
Another possibility is that your drop table command might be in the same batch as another statement that creates the table, in which case SSMS won't underline it because it knows that even though the table doesn't exist now, it will exist by the time that command is executed. For instance:
None of the tables one, two, or three existed in my database when I took this screenshot. If I highlight line 6 and try to run it by itself, it will fail. Yet you can see that two is not underlined on line 6 because SSMS can see that if I run the whole script, the table will be created on line 5. On the other hand, three is underlined on line 9 because I commented out the code that would have created it on line 8.
All of that said, I think we might be making too much of this problem. If you try to select from a table and SQL Server tells you it doesn't exist, then it doesn't exist. You can't rely on IntelliSense to tell you that it does; the two examples above are probably not the only ways that IntelliSense might mislead you about the current status of a table.
If you want the simplest way to know whether an object with a given name (like x_table) exists, just use:
select object_id('x_table');
If this query returns null, x_table doesn't exist, regardless of what IntelliSense is telling you. If it returns non-null, then there is some object out there with that name, and then the real question is why your select statement is failing. And to answer that, I'd need to see the statement.
A lot of posts like this, you have to copy in 2 statements :
CREATE TABLE newtable LIKE oldtable;
INSERT newtable SELECT * FROM oldtable;

Prevent update to non-existent rows

At work we have a table to hold settings which essentially contains the following columns:
PARAMNAME
VALUE
Most of the time new settings are added but on rare occasions, settings are removed. Unfortunately this means that any scripts which might have previously updated this value will continue to do so despite the fact that the update results in "0 rows updated" and leads to unexpected behaviour.
This situation was picked up recently by a regression test failure but only after much investigation into why the data in the system was different.
So my question is: Is there a way to generate an error condition when an update results in zero rows updated?
Here are some options I have thought of, but none of them are really all that desirable:
PL/SQL wrapper which notices the failed update and throws an exception.
Not ideal as it doesn't stop anyone/a script from manually doing an update.
A trigger on the table which throws an exception.
Goes against our current policy of phasing out triggers.
Requires updating trigger every time a setting is removed and maintaining a list of obsolete settings (if doing exclusion).
Might have problems with mutating table (if doing inclusion by querying what settings currently exist).
A PL/SQL wrapper seems like the best option to me. Triggers are a great thing to phase out, with the exception of generating sequences and inserting history records.
If you're concerned about someone manually updating rather than using the PL/SQL wrapper, just restrict the user role so that it does not have UPDATE privileges on the table but has EXECUTE privileges on the procedure.
Not really a solution but a method to organize things a bit:
Create a separate table with the parameter definitions and link to that table from the parameter value table. Make the reference to the parameter definition required (nulls not allowed).
Definition table PARAMS (ID, NAME)
Actual settings table PARAM_VALUES (PARAM_ID, VALUE)
(changing your table structure is also a very effective way to evoke errors in scripts that have not been updated...)
May be you can use MERGE statement
here is a link for it
http://www.oracle-developer.net/display.php?id=203
The merge statement allows you to combine insert and update in the same query, so in case the desired row does not exist you may insert a record in a buffer table to indicate the the row does not exist or else you can update the required record
Hope it helps

Why does a temp table work but not a permanent table?

I've written a SQL query for a report that creates a permanent table and then performs a bunch of inserts and updates to get all the data, according to company policy. It runs fine in SQL Server Management Studio and in Crystal Reports 2008 on my machine. However, when I schedule it to run on the server with SAP BusinessObjects Central Management Console, it fails with the error "Associated statement not prepared."
I have found that changing this permanent table to be a temp table makes the query work. Why would this be?
Some research shows that this error is sometimes sent instead of the true error. Other people reporting it talk of foreign key and (I would also assume) duplicate key errors.
Things I would check:
Does your permanent table have any unique constraints that might be violated? Or any foreign key constraints?
Are you creating indexes on the table after it has been created?
Are you creating any views over this permanent table?
What happens if the table already exists before the job is run?
What happens to the table if the job fails?
Are there any intermediate steps (such as within a stored procedure) that might involve additional temp or permanent tables?
ETA: Also check what schema the permanent table belongs to: is it usually created with "dbo"? Are you specifying that explicitly? Is there any chance that there might be a permissions problem?
That is often a generic error. Are you able to run it on the server as the account that it is scheduled to run as? It is most likely a permission error or constraint issue.
Assuming you really need a regular table, why it's not possible to create the permanent table once, vs creating it every time you run the query?
Recreating regular user table each time query runs does not seem right. But to make it work you may try to recreate the table in a separate batch or query (e.g. put GO in the script, that splits it into separate queries).
Regarding why it happens, I'm thinking about statement caching. Server compiles the query and stores the result for some time in case same query has to run again. So it's my speculation that it tries to run the compiled query which refers to the table you have already dropped and recreated under the same name. Name is the same, but physically it's a new table. You could hit some bug in the server this way. Just a speculation, it can be different kind of problem.
Without seeing code it's a guess, but being that you are creating a permanent table everytime you run the report, I assume you must be dropping the table at some point? (Or you'd have a LOT of tables building up over time.)
I suggest a couple angles to consider:
1) Make certain to prefix tables (perhaps by a session ID or soemthing) if you are concerned about concurrency/locking issues and the like so each report run has a table exclusive to itself.
2) If you are dropping the table at the end, instead adjust your logic to leave the table be. Write code that drops when you (re)start the operation. It's possible the report is clinging to the table and you are destroying it prematurely.

How to include the clients ip adress in to an audit as default constrain in sqlserver

Am writing av analytical standard solution register from the doping laboratory that i work for and got stuck on the problem how to get the ipaddress of the client in to the audit table.
I have found a straight forward method for actually get the ipaddress on the web and my question is not about that.
I got triggers on every table inserting records in to the audit table and I do not want to wright the inserting of the ipaddress manualy in every trigger. I would like to have something like a DEFAULT Constraint do the actual insertion of the ipaddress, but when I try I get errors about sub Queries not allowed.
Here is the way to get the address,
SELECT client_net_address
FROM sys.dm_exec_connections
WHERE (session_id = ##SPID)
You can use a SQL function as the DEFAULT constraint
http://msdn.microsoft.com/en-us/library/ms186755.aspx.
If using SQL isnt enough, you can use a CLR function as a default constraint.
http://msdn.microsoft.com/en-us/library/ms186755.aspx
The documentation specifies that a DEFAULT constraint can be "a constant, NULL, or a system function". Since there is no system function that returns the net address of the client, you cannot do what you want directly.
A trigger is the obvious solution here. Audit triggers are often created and maintained automatically from a template anyway, because they are usually identical on all tables, and if you aren't doing this already then perhaps this would be a good opportunity to start. That would avoid your issue with manually adding the code everywhere.