SQL Server Renaming Tables - sql-server

I'm switching contents of my tables by renaming them so the latest data goes to the main table. Does it automatically include the indexes on both tables as well?
EXEC sp_rename 'MAIN', 'TMP';
EXEC sp_rename 'LATEST', 'MAIN';
EXEC sp_rename 'TMP', 'LATEST';
Thanks!

Every table has an object_id and the name it is known by is just an attribute of that object. You could see each of the tables from your question listed in the sys.objects view with a query like this:
select *
from db_nm.sys.objects as o
where o.name in ('MAIN', 'TMP', 'LATEST')
and o.type = 'U' --filtering to (user-defined) Tables only
Each index, listed in the sys.indexes view, shows two IDs. The first is the index_id which is the ID of the index itself, and the object_id which is the ID of the object being indexed.
This means that when you use sp_rename to change the name of the table, the only thing that happens is the name attribute of the object is updated, and none of the ID numbers are being changed.
In other words, if index_a was pointing to object 123456 before renaming the table, it will still point to that object afterwards.
Update:
You can verify the table / index setup by using the query below which will return one record for each table / index combination.
select s.name as schema_nm
, o.name as table_nm
, i.name as index_nm
from db_nm.sys.objects as o
inner join db_nm.sys.schemas as s on o.schema_id = s.schema_id
left join db_nm.sys.indexes as i on o.object_id = i.object_id
where o.type = 'U'
and o.name in ('MAIN', 'TMP', 'LATEST')
order by 1, 2, 3

Related

Ordinal column position from sys schema

How can I get the following query, working on both views and tables, by using the SYS schema?
SELECT c.column_name,c.ordinal_position
from information_schema.columns c
where TABLE_SCHEMA='dbo'
and table_name='def_transaction_pt'
I have used the following until now, but I don't know where to get the ordinal column position from:
select *
from
sys.objects o
inner join sys.columns c on o.object_id=c.object_id
where o.name='def_transaction_pt'
You are on the right path...
DECLARE #ObjectName sysname = 'def_transaction_pt',
#SchemaName sysname = 'dbo'
SELECT c.name As Column_Name, ROW_NUMBER() OVER(ORDER BY c.column_id) As Ordinal_Position
FROM sys.columns AS c
JOIN sys.objects AS o
ON c.object_id = o.object_id
JOIN sys.schemas AS s
ON o.schema_id = s.schema_id
WHERE o.name = #ObjectName
AND s.name = #SchemaName
Note: I've only joined the sys.schemas to enable filtering using schema name,
and sys.objects to allow filtering using table/view name
After reading the comments and documentation, I've decided to adopt Larnu's suggestion about using row_number instead of the column_id directly.
Also, I've changed All_columns to Columns since it contains the columns from both tables and views.
BTW, the official documentation of information_schema.Columns describes the Ordinal_Position as "Column identification number." - which might be just the same as the Column_Id - It would require more testing to figure out that part.
BTW #2: Though you can't change the column's ordinal position using an alter table, it is possible to do using the visual designer (which in turn, drops and re-creates the table) - and if you do that, the column id for all columns is re-calculated, so it's always corresponding with the actual ordinal position (gaps aside).

Cannot delete primary key constraint in SQL Server

When I open designer for a table in SSMS, first column Id has a primary key assigned to it (IDENTITY), and key icon is shown next to it. In the Indexes / Keys window I can see a PK_dbo.Lines entry with Name [PK_dbo.Lines] and type Primary Key.
ALTER TABLE dbo.Lines DROP CONSTRAINT [PK_dbo.Lines]
returns
Msg 3728, Level 16, State 1, Line 33
'PK_dbo.Lines' is not a constraint.
If I execute
SELECT *
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
I can see primary keys for all tables, except for table Lines...
This query also does not return any results:
select object_name (parent_obj) ObjectName, name
from sysobjects
where xtype = 'PK'
and parent_obj = (object_id('[dbo].[Lines]'))
Any idea what is going on here?
If you make any changes to tables / columns in a database SSMS needs to be manually refreshed in order to correctly reflect these changes. Could it be that it is as simple as right-clicking on Tables and select refresh?
Alternatively, you might have spelled the PK name incorrectly? Please try the following script to remove the PK from the table 'Lines':
declare #PK_Name nvarchar(200);
declare #strSQL nvarchar(max);
select #PK_Name = (
select i.name as IndexName
from sys.indexes as i
inner join sys.index_columns as ic
on i.object_id = ic.object_id
and i.index_id = ic.index_id
inner join sys.tables as t
on t.object_id = i.object_id
where i.is_primary_key = 1
and t.name = N'Lines'
)
set #strSQL = N'ALTER TABLE dbo.Lines DROP CONSTRAINT ' + #PK_Name
execute(#strSQL)
First the script retrieves the correct name for the PK and then it tries to drop the PK constraint.

Locating a table in the database

When I run the following query I get the results as expected.
select * from [Beep].[Bopp]
Then, I ran the query below to "find" the table.
select * from sys.objects
where type='U'
and name like '%Bopp%'
It finds the table and lists the row describing it. However, I can't see any reference to Beep there. The name only contains Bopp, so I'm guessing that there a key that I need to look up but I don't know which column that is nor in what table to look it up.
edit
Based on the comments, I improved the query but I'm still not sure in what table to look up the actual name of the schema. The following gives me waaay to many hits (and setting the type didn't actually give me anything Beep-like.
select * from sys.tables t
left join sys.objects s
on t.schema_id = s.schema_id
where t.name like '%Bopp%'
I checked the objects for the specific name like so.
select * from sys.objects
where name like '%Beep%'
To my surprise, I didn't see any hits at all. Where is the little Beep-y thing hiding?!
You can use the schema_name() function against the schema_id column of sys.objects, like so:
select schema_name([schema_id]) from sys.objects where [name] like '%Bopp%';
Alternatively, you can query INFORMATION_SCHEMA.TABLES, which has a TABLE_SCHEMA column that gives the name of the schema rather than its id.
select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'Bopp';
Beep is the schema name for which you should attach another sys table like so:
select sys.schemas.name as schema_name, sys.objects.name as object_name
from sys.objects
INNER JOIN sys.schemas ON sys.objects.schema_id = sys.schemas.schema_id
where type='U'
and sys.objects.name like '%Bopp%'

list of tables without indexes in sql 2008

How do I list tables without indexes in my SQL 2008 database?
Edit
I want the Schema name and the Table name.
This should cover what your looking for. i.e. tables that are heaps (no clustered index) and do not have any non-clustered indexes. It uses the new sys. table objects used in 2005/2008.
in addition, you probably want to look for tables that do have a clustered index, but have no nonclustered indexes (this is the 2nd part of the statement which I've left commented out.
SELECT
schemaname = OBJECT_SCHEMA_NAME(o.object_id)
,tablename = o.NAME
FROM sys.objects o
INNER JOIN sys.indexes i ON i.OBJECT_ID = o.OBJECT_ID
-- tables that are heaps without any nonclustered indexes
WHERE (
o.type = 'U'
AND o.OBJECT_ID NOT IN (
SELECT OBJECT_ID
FROM sys.indexes
WHERE index_id > 0
)
)
-- OR
-- table that have a clustered index without any nonclustered indexes
--(o.type='U'
-- AND o.OBJECT_ID NOT IN (
-- SELECT OBJECT_ID
-- FROM sys.indexes
-- WHERE index_id>1))
Here's an example:
select SCHEMA_NAME(schema_id), name from sys.tables
where OBJECTPROPERTY(object_id, 'IsIndexed')= 0
In addition to #Philip Fourie's suggestion you might want to think about which indexes to create.
Once you have been accessing your data, SQL Server 2008 keeps track of places where it thinks indexes will be helpful (it refers to these as "missing indexes." There are a hand full of new Dynamic Managed Views which can show these missing indexes and some info about them.
From MSSQlTips:
sys.dm_db_missing_index_details - Returns detailed information about a missing index
sys.dm_db_missing_index_group_stats - Returns summary information about missing index groups
sys.dm_db_missing_index_groups - Returns information about a specific group of missing indexes
sys.dm_db_missing_index_columns(index_handle) - Returns information about the database table columns that are missing for an index. This is a function and requires the index_handle to be passed.
select shema = s.name, table_name = o.name
from sys.objects o
join sys.schemas s on o.schema_id = s.schema_id
where type = 'U'
and not exists (select i.index_id
from sys.indexes i
where i.type <> 0 --ignore default heap index row
and o.object_id = i.object_id )
Edit:
I have updated the SQL to include the Schema name as requested. (Note I had to sys.objects instead of sysobjects to cater for schemas that were introduced in SQL 2005)
The catalog tables are documented in the SQL Server documentation, see this link.
This FAQ contains more samples and might also be useful.
Note that these are system tables and can change between SQL server versions, where possible rather use the system table-independent views called Information Schema Views.
This code gives all the details about the indexes for all the tables:
SELECT
sch.name AS [Schema],
obj.name AS TableName,
indx.name AS IndexName,
CASE
WHEN indx.type_desc = 'HEAP' THEN 'N/A'
ELSE indx.type_desc
END AS IndexType
FROM sys.objects obj
JOIN sys.indexes indx ON indx.object_id = obj.object_id
JOIN sys.schemas AS sch ON sch.schema_id = obj.schema_id
WHERE
obj.type = 'U'
ORDER BY
obj.name

How do I get a list of tables affected by a set of stored procedures?

I have a huge database with some 100 tables and some 250 stored procedures. I want to know the list of tables affected by a subset of stored procedures. For example, I have a list of 50 stored procedures, out of 250, and I want to know the list of tables that will be affected by these 50 stored procedures. Is there any easy way for doing this, other than reading all the stored procedures and finding the list of tables manually?
PS: I am using SQL Server 2000 and SQL Server 2005 clients for this.
This would be your SQL Server query:
SELECT
[NAME]
FROM
sysobjects
WHERE
xType = 'U' AND --specifies a user table object
id in
(
SELECT
sd.depid
FROM
sysobjects so,
sysdepends sd
WHERE
so.name = 'NameOfStoredProcedure' AND
sd.id = so.id
)
Hope this helps someone.
sp_depends 'StoredProcName' will return the object name and object type that the stored proc depends on.
EDIT: I like #KG's answer better. More flexible IMHO.
I'd do it this way in SQL 2005 (uncomment the "AND" line if you only want it for a particular proc):
SELECT
[Proc] = SCHEMA_NAME(p.schema_id) + '.' + p.name,
[Table] = SCHEMA_NAME(t.schema_id) + '.' + t.name,
[Column] = c.name,
d.is_selected,
d.is_updated
FROM sys.procedures p
INNER JOIN sys.sql_dependencies d
ON d.object_id = p.object_id
AND d.class IN (0,1)
INNER JOIN sys.tables t
ON t.object_id = d.referenced_major_id
INNER JOIN sys.columns c
ON c.object_id = t.object_id
AND c.column_id = d.referenced_minor_id
WHERE p.type IN ('P')
-- AND p.object_id = OBJECT_ID('MyProc')
ORDER BY
1, 2, 3
One very invasive option would be to get a duplicate database and set a trigger on every table that logs that something happened. Then run all the SP's. If you can't do lots of mods to the DB that wont work
Also, be sure to add the logging to existing triggers rather than replace them with logging if you also want tables that the SP's effect via triggers.

Resources