Modify table creation date - sql-server-2005

Is it possible to modify the table creation date of a table? The date which we see on right clicking a table > properties > Created date or in sys.tables.create_date.
Even though the tables were created months ago, I want it to look like they were created today.

No more than you can change your birthday, and why would you want to ?
You could just
select * into #tmp from [tablename]
drop table [tablename]
select * into [tablename] from #tmp
That would rebuild the table and preserve the structure (to a point). You could script a new table , copy data then drop and rename. As above.

In SQL Server 2000, you could do this by hacking into the system tables with the sp_configure option 'allow updates' set to 1.
This is not possible in SQL Server 2005 and up. From Books Online:
This option is still present in the sp_configure stored procedure,
although its functionality is unavailable in Microsoft SQL Server 2005
(the setting has no effect). In SQL Server 2005, direct updates to the
system tables are not supported.
In 2005 I believe you could "game the system" by using a dedicated administrator connection, but I think that was fixed shortly after RTM (or it needs a trace flag or some other undocumented setting to work). Even using DAC and with the sp_configure option set to 1, trying this on both SQL Server 2005 SP4 and SQL Server 2008 R2 SP1 yields:
Msg 259, Level 16, State 1
Ad hoc updates to system catalogs are not allowed.
Who are you trying to fool, and why?
EDIT
Now that we have more information on the why, you could create a virtual machine that is not attached to any domain, set the clock back to whatever date you want, create a database, create your objects, back up the database, copy it to the host, and restore it. The create_date for those objects should still reflect the earlier date, though the database itself might not (I haven't tested this).
You can do this by shifting the clock back on your own system, but I don't know if I'd want to mess with my clock this way after SQL Server has been installed and has been creating objects in what will become "the future" for a short period of time. VM definitely seems safer to me.

Related

Creating an SQL Server Error Log using sp_readerror from multiple servers SQL Server 2012

I am attempting to create one single database to store all login errors.
insert into [dbo].[SQL_ErrorLog]
exec sp_readerrorlog 0, 1, 'error'
The above code gets me the information that I need for the current long and I understand that changing the 0 to a 1,2....etc will get me the previous days logs.
I have 4 different environments and instead of setting this same job up on each environment, I would like to control it all from 1 single job. I intend to add a field to determine which environment the log information is coming from.
I know that I could also set up staging tables on each environment and then run a select statement to pull in data from each staging table to the final table, however again I am trying to complete all the work from one environment if possible.
I have linked the other environments using the linked servers and can select data from any of them without a problem.
My question is more related on how I can run the exec sp_readerror stored procedure on the other server and insert that data into my master table.
An example would be:
Env0 - This is where the master table would be and where I would like to set everything up
Env1
Env2
Env3
I would like to be able to pull sp_readerror 0, 1, 'error' information from Env1, Env2, and Env3 and populate it on Env0 without using staging tables on each individual environment if possible.
Please let me know if this is not 100% clear. It makes sense in my head, however that does not always come out in text form. :)
Thanks in Advance.
If you are using linked servers it seems like you could link together multiple calls using go from the main source server. This will work assuming your linked servers are linked off one server.
INSERT INTO [Linked Server Name]. [some database name].[dbo].[SQL_ErrorLog]
EXEC [Linked Server Name].[some database name].[dbo].sp_readerrorlog
GO
INSERT INTO [Linked Server Name2]. [some database name].[dbo].[SQL_ErrorLog]
EXEC [Linked Server Name2].[some database name].[dbo].sp_readerrorlog
GO
INSERT INTO [Linked Server Name3]. [some database name].[dbo].[SQL_ErrorLog]
EXEC [Linked Server Name3].[some database name].[dbo].sp_readerrorlog
GO
INSERT INTO [Linked Server Name4]. [some database name].[dbo].[SQL_ErrorLog]
EXEC [Linked Server Name4].[some database name].[dbo].sp_readerrorlog
I think this will be your best bet. You can use the agent and then put all of these into the agent job and run the job. They will need to be fully qualified in order to run on the correct linked server.

Problem with SQL Server client DB upgrade script

SQL Server 2005, Win7, VS2008. I have to upgrade database from the old version of product to the newer one. I'd like to have one script that creates new database and upgrades old database to the new state. I am trying to do the following (SQL script below) and get the error (when running on machine with no database ):
Database 'MyDatabase' does not exist. Make sure that the name is
entered correctly.
The question is:
How can I specify database name in upgrade part
Is the better way to write create/upgrade exists ?
SQL code:
USE [master]
-- DB upgrade part
if exists (select name from sysdatabases where name = 'MyDatabase')
BEGIN
IF (<Some checks that DB is new>)
BEGIN
raiserror('MyDatabase database already exists and no upgrade required', 20, -1) with log
END
ELSE
BEGIN
USE [MyDatabase]
-- create some new tables
-- alter existing tables
raiserror('MyDatabase database upgraded successfully', 20, -1) with log
END
END
-- DB creating part
CREATE DATABASE [MyDatabase];
-- create new tables
You don't usually want to explicitly specify database name in a script. Rather, supply it exernally or pre-process the SQL to replace a $$DATABASENAME$$ token with the name of an actual database.
You're not going to be able to include the USE [MyDatabase] in your script since, if the database doesn't exist, the query won't parse.
Instead, what you can do is keep 2 separate scripts, one for an upgrade and one for a new database. Then you can call the scripts within the IF branches through xp_cmdshell and dynamic SQL. The following link has some examples that you can follow:
http://abhijitmore.wordpress.com/2011/06/21/how-to-execute-sql-using-t-sql/
PowerShell may make this task easier as well, but I don't have any direct experience using it.

Simplest SQL query never returns

I have a SQL query that is quite simply select * from tblOrders where customerID = 5000but it never returns. I waited 10 minutes and gave up.
The weirdest thing is that other queries on the same DB, but on another table, works fine. Removing the where-clause doesn't help either, so it seems like the table is somehow not responding. It's about 30000 lines, so it's not the biggest table either.
I'm using MS SQL SMS 2008 Express against a SQL Server 2008 express running on a remote server.
Try this to by-pass any locks on table -
select * from tblOrders(nolock) where customerID = 5000
It sounds like your table is locked
run this query to see what locks are held against it.
USE master;
GO
EXEC sp_lock;
GO
but table locking is a whole mindfield of its own
here is some info in the sp_lock system stored proc
http://msdn.microsoft.com/en-us/library/ms187749.aspx
when you find the lock you can kill it
KILL { session ID | UOW } [ WITH STATUSONLY ]
http://msdn.microsoft.com/en-us/library/ms173730.aspx
I agree with the others that this is most probably a locking issue. By default write access to a table still blocks read (only) access.
Since SQL Server 2005 this can be fixed by using the "row versioning". You need to change the settings of the database to enable this.
See the manual for a more detailed explanation:
http://msdn.microsoft.com/en-us/library/ms345124%28SQL.90%29.aspx

Is it possible to create a temp table on a linked server?

I'm doing some fairly complex queries against a remote linked server, and it would be useful to be able to store some information in temp tables and then perform joins against it - all with the remote data. Creating the temp tables locally and joining against them over the wire is prohibitively slow.
Is it possible to force the temp table to be created on the remote server? Assume I don't have sufficient privileges to create my own real (permanent) tables.
This works from SQL 2005 SP3 linked to SQL 2005 SP3 in my environment. However if you inspect the tempdb you will find that the table is actually on the local instance and not the remote instance. I have seen this as a resolution on other forums and wanted to steer you away from this.
create table SecondServer.#doll
(
name varchar(128)
)
GO
insert SecondServer.#Doll
select name from sys.objects where type = 'u'
select * from SecondServer.#Doll
I am 2 years late to the party but you can accomplish this using sp_executeSQL and feeding it a dynamic query to create the table remotely.
Exec RemoteServer.RemoteDatabase.RemoteSchema.SP_ExecuteSQL N'Create Table here'
This will execute the temp table creation at the remote location..
It's not possible to directly create temporary tables on a linked remote server. In fact you can't use any DDL against a linked server.
For more info on the guidelines and limitations of using linked servers see:
Guidelines for Using Distributed Queries (SQL 2008 Books Online)
One work around (and off the top of my head, and this would only work if you had permissions on the remote server) you could:
on the remote server have a stored procedure that would create a persistent table, with a name based on an IN parameter
the remote stored procedure would run a query then insert the results into this table
You then query locally against that table perform any joins to any local tables required
Call another stored procedure on the remote server to drop the remote table when you're done
Not ideal, but a possible work around.
Yes you can but it only lasts for the duration of the connection.
You need to use the EXECUTE AT syntax;
EXECUTE('SELECT * INTO ##example FROM sys.objects; WAITFOR DELAY ''00:01:00''') AT [SERVER2]
On SERVER2 the following will work (for 1 minute);
SELECT * FROM ##example
but it will not work on the local server.
Incidently if you open a transaction on the second server that uses ##example the object remains until the transaction is closed. It also stops the creating statement on the first server from completing. i.e. on server2 run and the transaction on server1 will continue indefinately.
BEGIN TRAN
SELECT * FROM ##example WITH (TABLOCKX)
This is more accademic than of practical use!
If memory is not much of an issue, you could also use table variables as an alternative to temporary tables. This worked for me when running a stored procedure with need of temporary data storage against a Linked Server.
More info: eg this comparison of table variables and temporary tables, including drawbacks of using table variables.

SQL Server: Snapshot transaction problem with synonyms in Express Edition

We have 2 databases, say DB1 and DB2.
DB1 contains all the stored procedures which access also data in DB2.
DB1 uses synonyms to access the tables in DB2.
(Using synonyms is a requirement in our situation)
This works perfectly fine in all situations with SQL Server 2005 Developer Edition.
However in the Express Edition, we get an exception when we do the following:
1 Restart SQL Server
2 Execute the following code within DB1:
set transaction isolation level snapshot
begin transaction
declare #sQuery varchar(max)
set #sQuery = 'Select * from synToSomeTableInDB2'
exec (#sQuery)
commit transaction
This will result in the following error:
Snapshot isolation transaction failed in database '...' because the database was not recovered when the current transaction was started. Retry the transaction after the database has recovered.
The same select query passes fine when used without the EXEC or when run on the Developer Edition.
Restarting the server in step 1 is important as once a connection was made to DB2, the code runs also fine on SQL Server Express Edition.
Does anyone have an idea what this is? We need to be able to use EXEC for some dynamic queries.
We've already checked MSDN, searched Google, ...
Any help is greatly appreciated.
--- Edit: March 10 09
As discussed with Ed Harper below, I've filed a bug report for this.
See https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=422150
As found out via Microsoft Connect, the problem is that by default on SQL Server Express Edition the AUTO_CLOSE option is set on true.
Changing this option to false fixes the problem.
The error message suggests that the query fails because SQL server is still recovering the database following the service restart when you execute your query.
Does the error always occur on the first attempt to run this code, regardless of the time elapsed since the service was restarted?
Can you confirm from the SQL Server log that the database is recovering correctly after the restart?