Tables created by default in user schema - sql-server

In Sql Server 2008, when I create a table without schema prefix:
create table mytable ( id int identify )
it usually ends up in the schema dbo, with name dbo.mytable.
However, on one of our servers, the tabel ends up belonging to me:
andomar.mytable
Which configuration difference could explain this?

It depends what your default schema is within that database. Even in SQL Server 2005, if your default schema in that one database is andomar, then any tables created without an explicit schema will end up there.
Check the user properties in that database (not the login properties) and see what the default schema is.

If you don't define schema in which you create table it will always use default one.
you can create it like this:
USE DataBaseName -- define database to use
GO
BEGIN TRAN - if you will have any error everything will roll back
CREATE TABLE testovi.razine - schema name is "testovi" and tablename is "razine"
(
id INT NOT NULL IDENTITY(1,1),
razina NVARCHAR(50) NULL,
razinaENG NVARCHAR(50) NULL,
kreirao UNIQUEIDENTIFIER NULL,
VrijemeKreiranja DATETIME NULL
)
ON [PRIMARY]
GO
When you create table always set constraint and index on column most used for transaction
ALTER TABLE testovi.razine ADD CONSTRAINT
PK_mat_razine PRIMARY KEY CLUSTERED
(id) WITH(IGNORE_DUP_KEY=OFF, --check duplicate and don't ignore if try to insert one
STATISTICS_NORECOMPUTE=OFF, -- important for statistic update and query optimization
ALLOW_PAGE_LOCKS=ON) -* I believe that this is default, but always put it to on if not
ON [PRIMARY]
GO
if ##error<>0
BEGIN
ROLBACK TRAN
END
ELSE
BEGIN
COMMIT TRAN --if everything passed o.k. table will be created
END
If you want to set default schema you have to know that it is user based default so you can set it with code:
USE espabiz -- database;
ALTER USER YourUserName WITH DERAULT_SCHEMA = SchemaName; -- SchemaName is default schema for defined user
Ping if you need additional help or mark answer it you find it usable :)

Related

ALTER COLUMN with INTEGER Datatype, NOT NULL, PRIMARY KEY, auto increment

I have a MySQL QUERY and working fine.
QUERY IS:
ALTER TABLE run
CHANGE RN_RUN_ID RN_RUN_ID INT(11) NOT NULL AUTO_INCREMENT,
ADD PRIMARY KEY (RN_RUN_ID);
I tried to execute same Query and modified in MSSQL which is throwing error.
MSSQL QUERY IS:
ALTER TABLE run ALTER COLUMN RN_RUN_ID
RN_RUN_ID INT NOT NULL AUTO_INCREMENT,
ADD PRIMARY KEY (RN_RUN_ID);
ERROR IS:
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near 'AUTO_INCREMENT'.
Can you tell me what I did wrong in this query.
You cant do it directly.
See this post: Adding an identity to an existing column
First answer.
In SQL Server there is no such AUTO_INCREMENT option. Please look at the docs. The equivalent is IDENTITY.
You cannot modify a column directly to become IDENTITY. You need to create a new column on the table, or create a new table and rename it. It has some tricky parts (allowing the insert in the identity column, renaming a column, and some other things). Look this SO answer.
There are also differences on the syntax for adding a PK to a table:
ALTER TABLE run
ADD CONSTRAINT PK PRIMARY KEY (rn_run_id)
If you have acces to SQL Server Management Studio you can get the full script easyly:
add a new diagram to the database
add the table to the diagram (rigth click on the window, and use the contextual menu)
save the diagram (you can delete it later)
right click on the table and choose custom view
right click again on the table, and choose "modify custom view". Add the identity, identity initial value, identity increment, key, etc. required elements to the custom view
modify the column properties in the diagram
go to the "Table designer" menu, and choose the last option "Generate change scripts". You'll get an script which does all the changes for you. For example:
An example of doing this process (by modifying the column id of the table test):
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Tmp_test
(
id int NOT NULL IDENTITY (10, 2)
) ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_test SET (LOCK_ESCALATION = TABLE)
GO
SET IDENTITY_INSERT dbo.Tmp_test ON
GO
IF EXISTS(SELECT * FROM dbo.test)
EXEC('INSERT INTO dbo.Tmp_test (id)
SELECT id FROM dbo.test WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT dbo.Tmp_test OFF
GO
DROP TABLE dbo.test
GO
EXECUTE sp_rename N'dbo.Tmp_test', N'test', 'OBJECT'
GO
COMMIT
NOTE: the name of the menu options can be different, i don't have an English SSMS at hand right now
Relevant docs:
IDENTITY
DBCC CHECKIDENT
SET IDENTITY_INSERT
ALTER TABLE

sql server change PK type from int to uniqueidentifier

I need to change the type of my primary key column on a table from int to guid. The database already has data that I don't want to lose, and there are foreign keys to consider. Is there a painless way to do this or do I have to manually do it through a big a** script?:) I would appreciate any suggestions
You'll have to do it the hard way, using scripts:
0) get in single user mode
1) add the new GUID column to the main table, and populate it.
2) add the new FK column to each child table and populate them with an UPDATE FROM
UPDATE c
SET FKcolumn=p.NewGuid
FROM ChildTable c
INNER JOIN ParentTable p ON p.OldIntID=c.OldIntId
3) drop the existing int FKs
4) drop the old int columns
5) add the new FKs on the guid column
6) get out of single user mode
you should be able to get SQL Server Management studio to generate the scripts for adding and dropping the columns and keys. Just make the changes in SSMS and click on the "Generate Change Script" toolbar icon and you can cut and paste the code to a text file.
Use option "Generate scripts" on your database in order to create "DROP/CREATE CONSTRAINT and INDEXES" (use advanced button to tune wizard).
Run portion of created SQL script to drop indexes and constraints.
Create one helper function and procedure as follows:
CREATE FUNCTION [dbo].[GuidFromHash]
(
#Input nvarchar(MAX)
)
RETURNS nvarchar(MAX)
AS
BEGIN
RETURN LOWER(SUBSTRING(#Input, 1,8)+'-'+SUBSTRING(#Input, 9,4)+'-'+SUBSTRING(#Input, 13,4)+'-'+SUBSTRING(#Input, 17,4)+'-'+SUBSTRING(#Input, 21,12))
END
CREATE PROCEDURE [dbo].[bigIntToGuid]
(
#table varchar(50),
#column varchar(50)
)
AS
DECLARE #SQL VARCHAR(MAX)
SET #SQL='UPDATE #Table SET #Column=dbo.HashToGuid(''cc''+CONVERT(VARCHAR, HASHBYTES(''MD5'',LTRIM(#Column)),2))'
SET #SQL=REPLACE(#SQL,'#Table',#Table)
SET #SQL=REPLACE(#SQL,'#Column',#Column)
EXEC(#SQL)
SET #SQL='SELECT * FROM #Table'
SET #SQL=REPLACE(#SQL,'#Table',#Table)
SET #SQL=REPLACE(#SQL,'#Column',#Column)
EXEC(#SQL)
Now comes the manual work for every table:
Open table in designer (SQL Management Studio or other tool)
Change bigint type of column to VARCHAR(50)
Execute "EXEC bigIntToGuid 'myTable','myBigIntColumn'
Back to table designer change column type to "uniqueidentifier"
Optionally you can add default value: newid(), and/or set column as primary key
Open your sql generated script created in step 1
Select only portion of the script for constraint and index creation, and execute it
This approach ensures converting int to guid and keep data integrity.

Problem with Indexed View in SQL Server, Error 8646

I was just prototyping a new system for deferring certain operations until out of hours on one of our databases. I've come up with (what I think) a pretty simple schema. I was first prototyping on SQL Server 2005 Express, but have confirmed the same problem on 2008 Developer. The error I'm getting is:
Msg 8646, Level 21, State 1, Procedure
Cancel, Line 6 Unable to find index
entry in index ID 1, of table
277576027, in database 'xxxxxx'. The
indicated index is corrupt or there is
a problem with the current update
plan. Run DBCC CHECKDB or DBCC
CHECKTABLE. If the problem persists,
contact product support.
The schema I'm using is:
create schema Writeback authorization dbo
create table Deferrals (
ClientID uniqueidentifier not null,
RequestedAt datetime not null,
CompletedAt datetime null,
CancelledAt datetime null,
ResolvedAt as ISNULL(CompletedAt,CancelledAt) persisted,
constraint PK_Writeback_Deferrals PRIMARY KEY (ClientID,RequestedAt) on [PRIMARY],
constraint CK_Writeback_Deferrals_NoTimeTravel CHECK ((RequestedAt <= CompletedAt) AND (RequestedAt <= CancelledAt)),
constraint CK_Writeback_Deferrals_NoSchrodinger CHECK ((CompletedAt is null) or (CancelledAt is null))
/* TODO:FOREIGN KEY */
)
create view Pending with schemabinding as
select
ClientID
from
Writeback.Deferrals
where
ResolvedAt is null
go
alter table Writeback.Deferrals add constraint
DF_Writeback_Deferrals_RequestedAt DEFAULT CURRENT_TIMESTAMP for RequestedAt
go
create unique clustered index PK_Writeback_Pending on Writeback.Pending (ClientID)
go
create procedure Writeback.Defer
#ClientID uniqueidentifier
as
set nocount on
insert into Writeback.Deferrals (ClientID)
select #ClientID
where not exists(select * from Writeback.Pending where ClientID = #ClientID)
go
create procedure Writeback.Cancel
#ClientID uniqueidentifier
as
set nocount on
update
Writeback.Deferrals
set
CancelledAt = CURRENT_TIMESTAMP
where
ClientID = #ClientID and
CompletedAt is null and
CancelledAt is null
go
create procedure Writeback.Complete
#ClientID uniqueidentifier
as
set nocount on
update
Writeback.Deferrals
set
CompletedAt = CURRENT_TIMESTAMP
where
ClientID = #ClientID and
CompletedAt is null and
CancelledAt is null
go
And the code that provokes the error is as follows:
declare #ClientA uniqueidentifier
declare #ClientB uniqueidentifier
select #ClientA = newid(),#ClientB = newid()
select * from Writeback.Pending
exec Writeback.Defer #ClientA
select * from Writeback.Pending
exec Writeback.Defer #ClientB
select * from Writeback.Pending
exec Writeback.Cancel #ClientB --<-- Error being raised here
select * from Writeback.Pending
exec Writeback.Complete #ClientA
select * from Writeback.Pending
select * from Writeback.Deferrals
I've seen a few others encountering such problems, but they seem to either have aggregates in their views (and a message back from MS saying they'd remove the ability to create such indexed views in 2005 SP 1), or they resolved it by applying a merge join in their join clause (but I don't have one).
Initially there was no computed column in the Deferrals table, and the where clause in the view was testing the CompletedAt and CancelledAt columns for NULL separately. But I changed to the above just to see if I could provoke different behaviour.
All of my SET options look right for using indexed views, and if they weren't, I'd expect a less violent error to be thrown.
Any ideas?
you have index corruption. run checkdb and see what errors it gives you. the easiest thing you could do is to rebuild your indexes.
also take a look at this KB article if it applies to your sitution.
Also note that putting a primary key on a GUID column will create a clustered index on it which is the worst thing performance wise you could do.
I managed to work out what's causing this error, by trying to build up this script, from scratch, adding in pieces as I went.
It's some kind of bug that's produced if the view is created as part of a CREATE SCHEMA statement. If I separate the CREATE SCHEMA into it's own batch, and then create the table and view in separate batches, everything works fine.
Long overdue edit - I raised this on Connect here. It was confirmed as being an issue in SQL Server 2008.
Internal builds (in 2010) indicated it was no longer an issue, and I have (just now, 2016) confirmed that the script in the question does not generate the same error in SQL Server 2012. The fix was not back-ported to SQL Server 2008.

SQL Server how to drop identity from a column

Is there an easy way to remove an identity from a table in SQL Server 2005?
When I use Management Studio, it generates a script that creates a mirror table without the identity, copies the data, drops the table, then renames the mirror table, etc. This script has 5231 lines in it because this table/column have many FK relations.
I'd feel much more comfortable running a simple alter/drop. Any ideas?
EDIT
I think I'm just going to go with the 5,231 line script from Enterprise Manager. However, I'm going to break it up into smaller parts which I can run and control better. This table "behaves" strange, if you try to delete 1 row (even one you just inserted, which is not in any other FK table), you get this error:
delete MyTable where MyPrimaryKey=1234
Msg 8621, Level 17, State 2, Line 1
The query processor ran out of stack space during query optimization. Please simplify the query.
No doubt, all the FKs. We will halt all access to our application and run in single user mode when we make these schema and related application changes. However, we need this to run fast, and I need an idea of how long it will take. I guess that I'll just have to test, test, test.
If you are on SQL Server 2005 or later, you can do this as a simple metadata change (NB: doesn't require an edition supporting partitioning as I originally stated).
Example code pilfered shamelessly from the workaround by Paul White on this Microsoft Connect Item.
USE tempdb;
GO
-- A table with an identity column
CREATE TABLE dbo.Source
(row_id INTEGER IDENTITY PRIMARY KEY NOT NULL, data SQL_VARIANT NULL);
GO
-- Some sample data
INSERT dbo.Source (data)
VALUES (CONVERT(SQL_VARIANT, 4)),
(CONVERT(SQL_VARIANT, 'X')),
(CONVERT(SQL_VARIANT, {d '2009-11-07'})),
(CONVERT(SQL_VARIANT, N'áéíóú'));
GO
-- Remove the identity property
BEGIN TRY;
-- All or nothing
BEGIN TRANSACTION;
-- A table with the same structure as the one with the identity column,
-- but without the identity property
CREATE TABLE dbo.Destination
(row_id INTEGER PRIMARY KEY NOT NULL, data SQL_VARIANT NULL);
-- Metadata switch
ALTER TABLE dbo.Source SWITCH TO dbo.Destination;
-- Drop the old object, which now contains no data
DROP TABLE dbo.Source;
-- Rename the new object to make it look like the old one
EXECUTE sp_rename N'dbo.Destination', N'Source', 'OBJECT';
-- Success
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
-- Bugger!
IF XACT_STATE() <> 0 ROLLBACK TRANSACTION;
PRINT ERROR_MESSAGE();
END CATCH;
GO
-- Test the the identity property has indeed gone
INSERT dbo.Source (row_id, data)
VALUES (5, CONVERT(SQL_VARIANT, N'This works!'))
SELECT row_id,
data
FROM dbo.Source;
GO
-- Tidy up
DROP TABLE dbo.Source;
I don't believe you can directly drop the IDENTITY part of the column. Your best bet is probably to:
add another non-identity column to the table
copy the identity values to that column
drop the original identity column
rename the new column to replace the original column
If the identity column is part of a key or other constraint, you will need to drop those constraints and re-create them after the above operations are complete.
You could add a column to the table that is not an identity column, copy the data, drop the original column, and rename the new column to the old column and recreate the indexes.
Here is a link that shows an example. Still not a simple alter, but it is certainly better than 5231 lines.

How do I alter a TEXT column on a database table in SQL server?

In a SQL server database, I have a table which contains a TEXT field which is set to allow NULLs. I need to change this to not allow NULLs. I can do this no problem via Enterprise Manager, but when I try to run the following script, alter table dbo.[EventLog] Alter column [Message] text Not null, I get an error:
Cannot alter column 'ErrorMessage' because it is 'text'.
Reading SQL Books Online does indeed reveal you are not allow to do an ALTER COLUMN on TEXT fields. I really need to be able to do this via a script though, and not manually in Enterprise Manager. What are the options for doing this in script then?
You can use Enterprise Manager to create your script. Right click on the table in EM and select Design. Uncheck the Allow Nulls column for the Text field. Instead of hitting the regular save icon (the floppy), click an icon that looks like a golden scroll with a tiny floppy or just do Table Designer > Generate Change Script from the menu. Save the script to a file so you can reuse it. Here is a sample script:
/* To prevent any potential data loss issues, you should review this script in detail before running it outside the context of the database designer.*/
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Tmp_TestTable
(
tableKey int NOT NULL,
Description varchar(50) NOT NULL,
TextData text NOT NULL
) ON [PRIMARY]
TEXTIMAGE_ON [PRIMARY]
GO
IF EXISTS(SELECT * FROM dbo.TestTable)
EXEC('INSERT INTO dbo.Tmp_TestTable (tableKey, Description, TextData)
SELECT tableKey, Description, TextData FROM dbo.TestTable WITH (HOLDLOCK TABLOCKX)')
GO
DROP TABLE dbo.TestTable
GO
EXECUTE sp_rename N'dbo.Tmp_TestTable', N'TestTable', 'OBJECT'
GO
ALTER TABLE dbo.TestTable ADD CONSTRAINT
PK_TestTable PRIMARY KEY CLUSTERED
(
tableKey
) ON [PRIMARY]
GO
COMMIT
Create a new field. Copy the data across. Drop the old field. Rename the new field.
I think getting rid of the null values is the easist.
(as raz0rf1sh has said)
CREATE TABLE tmp1( col1 INT identity ( 1, 1 ), col2 TEXT )
GO
INSERT
INTO tmp1
SELECT NULL
GO 10
SELECT *
FROM tmp1
UPDATE tmp1
SET col2 = ''
WHERE col2 IS NULL
ALTER TABLE tmp1
ALTER COLUMN col2 TEXT NOT NULL
SELECT *
FROM tmp1
DROP TABLE tmp1
Off the top of my head, I'd say you need to create a new table with the same structure as the existing table but with your text column set to not null and then run a query to move the records from one to the other.
I realize that's sort of a pseudocode answer but I think that's really the only option you've got.
If others with a better grip on the exact TSQL syntax care to supplement this answer, feel free.
I would update all the columns with NULL values and set it to an empty string, for example, ''. Then you should be able to run your ALTER TABLE script with no problems. A lot less work than creating a new column.
Try to generate the change script from within Enterprise Manager to see how it is done there

Resources