Collation Conflict in SSRS - sql

Currently using SQL Server 2014 and having an issue with the Collation on a stored procedure. I currently have a report that runs a stored procedure, the code works fine when run in SSMS but I have noticed that while it is being run as part of a SSRS report there is a collation issue between Latin1_General_CI_AS_KS_WS and Latin1_General_CI_AS.
My database is set at Latin1_General_CI_AS as well as all my table columns so I am at a loss as to where it is pulling this Latin1_General_CI_AS_KS_WS inconsistency, can anyone offer any suggestions?
Thanks

Latin1_General_CI_AS_KS_WS is the default collation for SSRS.
Either you write your SQL queries with the COLLATE property on all your string comparisons or reinstall SSRS with the correct default collation.
Keep in mind that if you use ALTER DATABASE to change the SSRS database collation, it won't affect already created objects, just new ones from that point onwards.
If this is a problem with a particular column (and not the whole database), you can run this query to check all column's current collation.
SELECT
ColumnName = QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + '.' + QUOTENAME(c.name),
Collation = c.collation_name
FROM
sys.schemas s
INNER JOIN sys.tables t ON t.schema_id = s.schema_id
INNER JOIN sys.columns c ON c.object_id = t.object_id
WHERE
C.collation_name is not null
ORDER BY
1
Then use ALTER TABLE <tablename> ALTER COLUMN <columnname> <type> COLLATE <newCollate> to change it.

Related

What does this SQL error really mean? [duplicate]

I have the following code
SELECT tA.FieldName As [Field Name],
COALESCE(tO_A.[desc], tO_B.[desc], tO_C.Name, tA.OldVAlue) AS [Old Value],
COALESCE(tN_A.[desc], tN_B.[desc], tN_C.Name, tA.NewValue) AS [New Value],
U.UserName AS [User Name],
CONVERT(varchar, tA.ChangeDate) AS [Change Date]
FROM D tA
JOIN
[DRTS].[dbo].[User] U
ON tA.UserID = U.UserID
LEFT JOIN
A tO_A
on tA.FieldName = 'AID'
AND tA.oldValue = CONVERT(VARCHAR, tO_A.ID)
LEFT JOIN
A tN_A
on tA.FieldName = 'AID'
AND tA.newValue = CONVERT(VARCHAR, tN_A.ID)
LEFT JOIN
B tO_B
on tA.FieldName = 'BID'
AND tA.oldValue = CONVERT(VARCHAR, tO_B.ID)
LEFT JOIN
B tN_B
on tA.FieldName = 'BID'
AND tA.newValue = CONVERT(VARCHAR, tN_B.ID)
LEFT JOIN
C tO_C
on tA.FieldName = 'CID'
AND tA.oldValue = tO_C.Name
LEFT JOIN
C tN_C
on tA.FieldName = 'CID'
AND tA.newValue = tN_C.Name
WHERE U.Fullname = #SearchTerm
ORDER BY tA.ChangeDate
When running the code I am getting the error pasted in the title after adding the two joins for table C. I think this may have something to do with the fact I'm using SQL Server 2008 and have restored a copy of this db on to my machine which is 2005.
I do the following:
...WHERE
fieldname COLLATE DATABASE_DEFAULT = otherfieldname COLLATE DATABASE_DEFAULT
Works every time. :)
You have a mismatch of two different collations in your table. You can check what collations each column in your table(s) has by using this query:
SELECT
col.name, col.collation_name
FROM
sys.columns col
WHERE
object_id = OBJECT_ID('YourTableName')
Collations are needed and used when ordering and comparing strings. It's generally a good idea to have a single, unique collation used throughout your database - don't use different collations within a single table or database - you're only asking for trouble....
Once you've settled for one single collation, you can change those tables / columns that don't match yet using this command:
ALTER TABLE YourTableName
ALTER COLUMN OffendingColumn
VARCHAR(100) COLLATE Latin1_General_CI_AS NOT NULL
To find the fulltext indices in your database, use this query here:
SELECT
fti.object_Id,
OBJECT_NAME(fti.object_id) 'Fulltext index',
fti.is_enabled,
i.name 'Index name',
OBJECT_NAME(i.object_id) 'Table name'
FROM
sys.fulltext_indexes fti
INNER JOIN
sys.indexes i ON fti.unique_index_id = i.index_id
You can then drop the fulltext index using:
DROP FULLTEXT INDEX ON (tablename)
Use the collate clause in your query:
LEFT JOIN C tO_C on tA.FieldName = 'CID' AND tA.oldValue COLLATE Latin1_General_CI_AS = tO_C.Name
I may not have the syntax exactly right (check BOL), but you can do this to change the collation on-the-fly for the query - you may need to add the clause for each join.
edit: I realized this was not quite right - the collate clause goes after the field you need to change - in this example I changed the collation on the tA.oldValue field.
Identify the fields for which it is throwing this error and add following to them:
COLLATE DATABASE_DEFAULT
There are two tables joined on Code field:
...
and table1.Code = table2.Code
...
Update your query to:
...
and table1.Code COLLATE DATABASE_DEFAULT = table2.Code COLLATE DATABASE_DEFAULT
...
This can easily happen when you have 2 different databases and specially 2 different databases from 2 different servers. Best option is to change it to a common collection and do the join or comparison.
SELECT
*
FROM sd
INNER JOIN pd ON sd.SCaseflowID COLLATE Latin1_General_CS_AS = pd.PDebt_code COLLATE Latin1_General_CS_AS
#Valkyrie awesome answer. Thought I put in here a case when performing the same with a subquery insides a stored procedure, as I wondered if your answer works in this case, and it did awesome.
...WHERE fieldname COLLATE DATABASE_DEFAULT in (
SELECT DISTINCT otherfieldname COLLATE DATABASE_DEFAULT
FROM ...
WHERE ...
)
In the where criteria add collate SQL_Latin1_General_CP1_CI_AS
This works for me.
WHERE U.Fullname = #SearchTerm collate SQL_Latin1_General_CP1_CI_AS
To resolve this problem in the query without changing either database, you can cast the expressions on other side of the "=" sign with
COLLATE SQL_Latin1_General_CP1_CI_AS
as suggested here.
The root cause is that the sql server database you took the schema from has a collation that differs from your local installation. If you don't want to worry about collation re install SQL Server locally using the same collation as the SQL Server 2008 database.
error (Cannot resolve the collation conflict between .... ) usually occurs while comparing data from multiple databases.
since you cannot change the collation of databases now, use COLLATE DATABASE_DEFAULT.
----------
AND db1.tbl1.fiel1 COLLATE DATABASE_DEFAULT =db2.tbl2.field2 COLLATE DATABASE_DEFAULT
I have had something like this before, and what we found was that the collation between 2 tables were different.
Check that these are the same.
Thanks to marc_s's answer I solved my original problem - inspired to take it a step further and post one approach to transforming a whole table at a time - tsql script to generate the alter column statements:
DECLARE #tableName VARCHAR(MAX)
SET #tableName = 'affiliate'
--EXEC sp_columns #tableName
SELECT 'Alter table ' + #tableName + ' alter column ' + col.name
+ CASE ( col.user_type_id )
WHEN 231
THEN ' nvarchar(' + CAST(col.max_length / 2 AS VARCHAR) + ') '
END + 'collate Latin1_General_CI_AS ' + CASE ( col.is_nullable )
WHEN 0 THEN ' not null'
WHEN 1 THEN ' null'
END
FROM sys.columns col
WHERE object_id = OBJECT_ID(#tableName)
gets:
ALTER TABLE Affiliate ALTER COLUMN myTable NVARCHAR(4000) COLLATE Latin1_General_CI_AS NOT NULL
I'll admit to being puzzled by the need to col.max_length / 2 -
Check the level of collation that is mismatched (server, database,table,column,character).
If it is the server, these steps helped me once:
Stop the server
Find your sqlservr.exe tool
Run this command:
sqlservr -m -T4022 -T3659 -s"name_of_insance"
-q "name_of_collation"
Start your sql server:
net start name_of_instance
Check the collation of your server again.
Here is more info:
https://www.mssqltips.com/sqlservertip/3519/changing-sql-server-collation-after-installation/
I have used the content from this site to create the following script which changes collation of all columns in all tables:
CREATE PROCEDURE [dbo].[sz_pipeline001_collation]
-- Add the parameters for the stored procedure here
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT 'ALTER TABLE [' + SYSOBJECTS.Name + '] ALTER COLUMN [' + SYSCOLUMNS.Name + '] ' +
SYSTYPES.name +
CASE systypes.NAME
WHEN 'text' THEN ' '
ELSE
'(' + RTRIM(CASE SYSCOLUMNS.length
WHEN -1 THEN 'MAX'
ELSE CONVERT(CHAR,SYSCOLUMNS.length)
END) + ') '
END
+ ' ' + ' COLLATE Latin1_General_CI_AS ' + CASE ISNULLABLE WHEN 0 THEN 'NOT NULL' ELSE 'NULL' END
FROM SYSCOLUMNS , SYSOBJECTS , SYSTYPES
WHERE SYSCOLUMNS.ID = SYSOBJECTS.ID
AND SYSOBJECTS.TYPE = 'U'
AND SYSTYPES.Xtype = SYSCOLUMNS.xtype
AND SYSCOLUMNS.COLLATION IS NOT NULL
AND NOT ( sysobjects.NAME LIKE 'sys%' )
AND NOT ( SYSTYPES.name LIKE 'sys%' )
END
If this occurs across the whole of your DB then it's better to change your DB collation like so:
USE master;
GO
ALTER DATABASE MyOptionsTest
COLLATE << INSERT COLATION REQUIRED >> ;
GO
--Verify the collation setting.
SELECT name, collation_name
FROM sys.databases
WHERE name = N'<< INSERT DATABASE NAME >>';
GO
Reference here
For those who have a CREATE DATABASE script (as was my case) for the database that is causing this issue you can use the following CREATE script to match the collation:
-- Create Case Sensitive Database
CREATE DATABASE CaseSensitiveDatabase
COLLATE SQL_Latin1_General_CP1_CS_AS -- or any collation you require
GO
USE CaseSensitiveDatabase
GO
SELECT *
FROM sys.types
GO
--rest of your script here
or
-- Create Case In-Sensitive Database
CREATE DATABASE CaseInSensitiveDatabase
COLLATE SQL_Latin1_General_CP1_CI_AS -- or any collation you require
GO
USE CaseInSensitiveDatabase
GO
SELECT *
FROM sys.types
GO
--rest of your script here
This applies the desired collation to all the tables, which was just what I needed. It is ideal to try and keep the collation the same for all databases on a server.
Hope this helps.
More info on the following link: SQL SERVER – Creating Database with Different Collation on Server
You could easily do this by using 4 easy steps
backup your database, just incase
change database collation: right click database, select properties, go to the options and change the collation to the required collation.
Generate a script to Drop and Recreate all your database objects: right click your database, select tasks, select generate script... ( make sure you select Drop & Create on the Advanced options of the Wizard, Also select Schema & Data )
Run the Script Generated above
INSERT INTO eSSLSmartOfficeSource2.[dbo].DeviceLogs (DeviceId,UserId,LogDate,UpdateFlag)
SELECT DL1.DeviceId ,DL1.UserId COLLATE DATABASE_DEFAULT,DL1.LogDate
,0 FROM eSSLSmartOffice.[dbo].DeviceLogs DL1
WHERE NOT EXISTS
(SELECT DL2.DeviceId ,DL2.UserId COLLATE DATABASE_DEFAULT
,DL2.LogDate ,DL2.UpdateFlag
FROM eSSLSmartOfficeSource2.[dbo].DeviceLogs DL2
WHERE DL1.DeviceId =DL2.DeviceId
and DL1.UserId collate Latin1_General_CS_AS=DL2.UserId collate Latin1_General_CS_AS
and DL1.LogDate =DL2.LogDate )
Added code to #JustSteve's answer to deal with varchar and varchar(MAX) columns:
DECLARE #tableName VARCHAR(MAX)
SET #tableName = 'first_notes'
--EXEC sp_columns #tableName
SELECT 'Alter table ' + #tableName + ' alter column ' + col.name
+ CASE ( col.user_type_id )
WHEN 231
THEN ' nvarchar(' + CAST(col.max_length / 2 AS VARCHAR) + ') '
WHEN 167
THEN ' varchar(' + CASE col.max_length
WHEN -1
THEN 'MAX'
ELSE
CAST(col.max_length AS VARCHAR)
end
+ ') '
END + 'collate Latin1_General_CI_AS ' + CASE ( col.is_nullable )
WHEN 0 THEN ' not null'
WHEN 1 THEN ' null'
END
FROM sys.columns col
WHERE object_id = OBJECT_ID(#tableName)
I had a similar error (Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "SQL_Latin1_General_CP1250_CI_AS" in the INTERSECT operation), when I used old jdbc driver.
I resolved this by downloading new driver from Microsoft or open-source project jTDS.
here is what we did, in our situation we need an ad hoc query to be executed using a date restriction on demand, and the query is defined in a table.
Our new query needs to match data between different databases and include data from both of them.
It seems that the COLLATION is different between the db that imports data from the iSeries/AS400 system, and our reporting database - this could be because of the specific data types (such as Greek accents on names and so on).
So we used the below join clause:
...LEFT Outer join ImportDB..C4CTP C4 on C4.C4CTP COLLATE Latin1_General_CS_AS=CUS_Type COLLATE Latin1_General_CS_AS
You may not have any collation issues in your database whatsoever, but if you restored a copy of your database from a backup on a server with a different collation than the origin, and your code is creating temporary tables, those temporary tables would inherit collation from the server and there would be conflicts with your database.
ALTER DATABASE test2 --put your database name here
COLLATE Latin1_General_CS_AS --replace with the collation you need
I had a similar requirement; documenting my approach here for anyone with a similar scenario...
Scenario
I have a database from a clean install with the correct collations.
I have another database which has the wrong collations.
I need to update the latter to use the collations defined on the former.
Solution
Use SQL Server Schema Comparison (from SQL Server Data Tools / Visual Studio) to compare source (clean install) with destination (the db with invalid collation).
In my case I compared the two DBs directly; though you could work via a project to allow you to manually tweak pieces in between...
Run Visual Studio
Create a new SQL Server Data Project
Click Tools, SQL Server, New Schema Comparison
Select the source database
Select the target database
Click options (⚙)
Under Object Types select only those types you're interested in (for me it was only Views and Tables)
Under General select:
Block on possible data loss
Disable & reenable DDL triggers
Ignore cryptographic provider file path
Ignore File & Log File Path
Ignore file size
Ignore filegroup placement
Ignore full text catalog file path
Ignore keyword casing
Ignore login SIDs
Ignore quoted identifiers
Ignore route lifetime
Ignore semicolon between statements
Ignore whitespace
Script refresh module
Script validation for new constraints
Verify collation compatibility
Verify deployment
Click Compare
Uncheck any objects flagged for deletion (NB: those may still have collation issues; but since they're not defined in our source/template db we don't know; either way, we don't want to lose things if we're only targeting collation changes). You can unchceck all at once by right clicking on the DELETE folder and selecting EXCLUDE.
Likewise exclude for any CREATE objects (here since they don't exist in the target they can't have the wrong collation there; whether they should exist is a question for another topic).
Click on each object under CHANGE to see the script for that object. Use the diff to ensure that we're only changing the collation (anything other differences manually detected you'll likely want to exclude / handle those objects manually).
Click Update to push changes
This does still involve some manual effort (e.g. checking that you're only impacting the collation) - but it handles dependencies for you.
Also you can keep a database project of the valid schema so you can use a universal template for your DBs should you have more than 1 to update, assuming all target DBs should end up with the same schema.
You can also use find/replace on the files in a database project should you wish to mass amend settings there (e.g. so you could create the project from the invalid database using schema compare, amend the project files, then toggle the source/target in the schema compare to push your changes back to the DB).
I read practically every answer and comment here so far. It got me to an easy solution by combining the responses made. So here is how it was easy for me to resolved:
Create a script of the database. Right-click database > Tasks > Generate Script. Be sure to include Schema and Data
Delete the database after you have saved the script. Right-click database > Delete
Remove the part of the script that will recreate the database, ie, delete everything upto the first line that starts with:
USE < DATABASENAME >
GO
Create the database 'manually', ie, right-click on Tables > Create database...
Run the script that sets the default collation that you want for the new empty database.
USE master;
GO
ALTER DATABASE << DatabaseName >>
COLLATE << INSERT COLATION REQUIRED >> ;
GO
Run the script you saved to recreate the database
Credit to
#Justin for providing the script to check the collation on the database, and how to update it
#RockScience for mentioning that the change on collation will only apply to new tables/objects
#Felix Mwiti Mugambi (acknowledging my fellow Kenyan :) ) for indicating the need to recreate the database. (I usually avoid dropping and creating for complex databases)

Query to get the information of Databases used by Stored Procedure in SQL server 2005

Is there any query in SQL server 2005 that returns the list of Stored procedures in the particular database along with the name of databases whose objects are getting used in the stored procedure.
That is how to get all procedure names:
select *
from DatabaseName.information_schema.routines
where routine_type = 'PROCEDURE'
I will check now, if there is any way to check their code for table names.
you can use this query
it will show all dependencies even to the columns
SELECT
--SP, View, or Function
ReferencingName = o.name,
ReferencingType = o.type_desc,
--Referenced Field
ref.referenced_database_name, --will be null if the DB is not explicitly called out
ref.referenced_schema_name, --will be null or blank if the DB is not explicitly called out
ref.referenced_entity_name,
ref.referenced_minor_name
FROM sys.objects AS o
cross apply sys.dm_sql_referenced_entities('dbo.' + o.name, 'Object') ref
where o.type = 'p'
-- for other database object types use below line
-- o.type in ('FN','IF','V','P','TF')
works for single database
select *
from information_schema.routines
where routine_type = 'PROCEDURE'
This is not a simple thing to do reliably in SQL Server 2005. You might want to look at commercial products such as ApexSQL Clean or SQL Dependency Tracker.
In SQL Server 2008 you could try using the sys.sql_expression_dependencies dynamic management view. For example,
select
quotename(s.name) + N'.' + quotename(o.name) as ProcedureName,
ed.referenced_server_name,
ed.referenced_database_name,
ed.referenced_schema_name,
ed.referenced_entity_name
from sys.sql_expression_dependencies ed
inner join sys.objects o on o.object_id = ed.referencing_id
inner join sys.schemas s on s.schema_id = o.schema_id
where
o.type = 'P'
Hope this helps,
Rhys

Find and replace content in stored procedures ms sql server

I want to rename tables and views which are used in stored procedures. Is there any way to find and replace table names in stored procedures, maybe there is tool for ms sql server (i'm using ms sql server 2012).
SQL Server might not allow you to directly UPDATE the object definitions (Views and Stored Proceduress in your case) present in the System catalogs even after setting the 'Allow Updates' option to 1.
The following code will generate the required ALTER Script and you can run them manually after reviewing the definitions ([ModifiedDefinition] )or u can loop through each value of [ModifiedDefinition] and run it using sp_executesql.
SELECT
b.Name AS [ObjectName],
CASE WHEN b.type ='p' THEN 'Stored Procedure'
WHEN b.type ='v' THEN 'View'
ELSE b.TYPE
END AS [ObjectType]
,a.definition AS [Definition]
,Replace ((REPLACE(definition,'OLD Value','New Value')),'Create','ALTER') AS [ModifiedDefinition]
FROM sys.sql_modules a
JOIN
( select type, name,object_id
from sys.objects
where type in (
'p' -- procedures
,'v'--views
)
and is_ms_shipped = 0
)b
ON a.object_id=b.object_id
And as always, be careful with production data and take backups before performing bulk changes on object definitions!!
You can use DBvisualizer .. it pretty much works with all databases and with ms sql too, you can do all you mentioned by using this.
I answered this on another topic (https://stackoverflow.com/a/67728039/11165834) , I do it using the following script:
DECLARE #queryDef NVARCHAR(max)
WHILE EXISTS (
SELECT 1
FROM sys.sql_modules sm
JOIN sys.objects o ON sm.object_id = o.object_id
WHERE sm.definition LIKE '%TEXT_TO_REPLACE%'
AND o.type = 'V'
)
BEGIN
-- TO ALTER THE VIEW AUTOMATICALLY
SET #queryDef = ( SELECT TOP 1 Replace (Replace (sm.definition, 'CREATE VIEW', 'ALTER VIEW'),
'TEXT_TO_REPLACE',
'NEW_TEXT')
FROM sys.sql_modules sm
JOIN sys.objects o ON sm.object_id = o.object_id
WHERE sm.definition LIKE '%TEXT_TO_REPLACE%'
AND o.type = 'V')
EXEC (#queryDef)
END
I use it to replace procedures/views when I restore a backup from production into tests databases.
As #S.A said, be verry careful because is not a verry safe way.
Change the "o.type" and "Replace (sm.definition, 'CREATE VIEW', 'ALTER VIEW'" accordingly to your need

how do I reset collation for all columns in the database?

I need to reset collation for all columns in all tables in the database:
I want to use default collation of database
I tried to change it under database properties:
but collation already setted in columns and it mean that i cannot overwrite it
anybody has script that can do it for me?
I've knocked together a script that should do a decent enough job (hopefully). Run the script in the appropriate database, with results as text. Then Copy & Paste the output into a script window to change the collation of each column:
declare #NewCollationName sysname
set #NewCollationName = 'Latin1_General_CS_AS'
select
'ALTER TABLE ' + QUOTENAME(SCHEMA_NAME(st.schema_id)) + '.' + QUOTENAME(st.name) +
' ALTER COLUMN ' + QUOTENAME(sc.name) + ' ' + styp.name + '(' +
CASE WHEN sc.max_length = -1 THEN 'max' ELSE CONVERT(varchar(10),sc.max_length) END +
') collate ' + #NewCollationName + '
go
'
from
sys.columns sc
inner join
sys.tables st
on
sc.object_id = st.object_id
inner join
sys.types styp
on
sc.user_type_id = styp.user_type_id
where
sc.collation_name is not null and
OBJECTPROPERTY(st.object_id,N'IsMSShipped')=0
One thing to note, however, is that the generated script won't work if the columns are the target of constraints or targetted by a schema bound object (view or function).
In such cases, you'd have to script out the dependent objects, drop them from the database, then run the script generated by the script above, and finally re-add the dependent objects.
See (Changing the Database Collation) http://msdn.microsoft.com/en-us/library/ms174269.aspx
ALTER DATABASE database_name COLLATE collation_name
The fastest way to reset a column would be to SET UNUSED the column, then add a column with the same name and datatype.
This will be the fastest way since both operations will not touch the actual table (only dictionary update).
The actual ordering of the columns will be changed (the reset column will be the last column). If your code rely on the ordering of the columns (it should not!) you can create a view that will have the column in the right order (rename table, create view with the same name as old table, revoke grants from base table, add grants to view).
The SET UNUSED method will not reclaim the space used by the column (whereas dropping the column will free space in each block).
Hope this helps.
A proposed script (can be found here) is meant to iterate through all tables in your DB and changing the collation to the desired one.
It is based on the script:
ALTER TABLE TABLENAME ALTER COLUMN COLUMNNAME varchar(100) COLLATE Latin1_General_CI_AS NULL

T-SQL Scripts to copy all table constraints

I have created many tables on my local database and moved them to production database.
Now I am working on fine tuning the database and created many constraints on my local database tables such as PK, FK, Default Values, Indexes etc. etc.
Now I would like to copy only these constraints to production database. Is there a way to do it?
Please note that my production database tables already populated with some data. So I can’t drop and recreate them.
If you don't want to buy any tools (which are totally worth their price, BTW), you can always interrogate the system catalog views, and extract the info from there to create scripts you could execute on your new database.
In the case of e.g. the default constraints, this query shows you a list of all the default constraints in your database:
SELECT
dc.name 'Constraint Name',
OBJECT_NAME(parent_object_id) 'Table Name',
c.name 'Column Name',
definition
FROM
sys.default_constraints dc
INNER JOIN
sys.columns c ON dc.parent_object_id = c.object_id
AND dc.parent_column_id = c.column_id
ORDER BY
OBJECT_NAME(parent_object_id), c.name
and based on that, you could of course create a query which would emit T-SQL statements to recreate those default constraints on your target server:
SELECT
'ALTER TABLE ' + OBJECT_SCHEMA_NAME(dc.parent_object_id) + '.' + OBJECT_NAME(dc.parent_object_id) +
' ADD CONSTRAINT ' + dc.name + ' DEFAULT(' + definition
+ ') FOR ' + c.name
FROM
sys.default_constraints dc
INNER JOIN
sys.columns c ON dc.parent_object_id = c.object_id
AND dc.parent_column_id = c.column_id
You'd get something like this (for the AdventureWorks sample DB):
ALTER TABLE dbo.Store ADD CONSTRAINT DF_Store_rowguid DEFAULT((newid())) FOR rowguid
ALTER TABLE dbo.Store ADD CONSTRAINT DF_Store_ModifiedDate DEFAULT((getdate())) FOR ModifiedDate
ALTER TABLE dbo.ProductPhoto ADD CONSTRAINT DF_ProductPhoto_ModifiedDate DEFAULT((getdate())) FOR ModifiedDate
ALTER TABLE dbo.ProductProductPhoto ADD CONSTRAINT DF_ProductProductPhoto_Primary DEFAULT(((0))) FOR Primary
ALTER TABLE dbo.ProductProductPhoto ADD CONSTRAINT DF_ProductProductPhoto_ModifiedDate DEFAULT((getdate())) FOR ModifiedDate
ALTER TABLE dbo.StoreContact ADD CONSTRAINT DF_StoreContact_rowguid DEFAULT((newid())) FOR rowguid
ALTER TABLE dbo.StoreContact ADD CONSTRAINT DF_StoreContact_ModifiedDate DEFAULT((getdate())) FOR ModifiedDate
ALTER TABLE dbo.Address ADD CONSTRAINT DF_Address_rowguid DEFAULT((newid())) FOR rowguid
Of course, you could tweak the resulting T-SQL being output to your liking - but basically, copy&paste those results from the query to your new database, and off you go.
Of course, there are similar system catalog views for foreign key relationships (sys.foreign_keys), check constraints (sys.check_constraints), indexes (sys.indexes and sys.index_columns) and many more.
It's a bit of work - but it can be done on your own time, and you'll learn a lot about SQL Server in the process.
So it's a traditional "make or buy" decision all over again :-)
Marc
The best way would be to store all your DDL code in a source control. Then deploy it to production using tools like dbGhost (my favorite) or SQL Compare
Red Gate's SQL Compare is a popular, non-free way to do this.
Sure this is an old post, but none of the scripts in all the above answers put out the table schemas as well. So it didn't work out the box for my database.
This one does, so it did:
-- ===========================================================
-- Default Constraints
-- How to script out Default Constraints in SQL Server 2005+
-- ===========================================================
-- view results in text, to make copying and pasting easier
-- drop default constraints
SELECT
'ALTER TABLE ' +
QuoteName(OBJECT_SCHEMA_NAME(sc.id)) + '.' + QUOTENAME(OBJECT_NAME(sc.id)) +
CHAR(10) +
' DROP CONSTRAINT ' +
QuoteName(OBJECT_NAME(sc.cdefault))
FROM
syscolumns sc
INNER JOIN
sysobjects as so on sc.cdefault = so.id
INNER JOIN
syscomments as sm on sc.cdefault = sm.id
WHERE
OBJECTPROPERTY(so.id, N'IsDefaultCnst') = 1
-- create default constraints
SELECT
'ALTER TABLE ' +
QuoteName(OBJECT_SCHEMA_NAME(sc.id)) + '.' + QuoteName(OBJECT_NAME(sc.id)) +
' ADD CONSTRAINT ' +
QuoteName(OBJECT_NAME(sc.cdefault))+
' DEFAULT ' +
sm.text +
' FOR ' + QuoteName(sc.name)
+ CHAR(13)+CHAR(10)
FROM
syscolumns sc
INNER JOIN
sysobjects as so on sc.cdefault = so.id
INNER JOIN
syscomments as sm on sc.cdefault = sm.id
WHERE
OBJECTPROPERTY(so.id, N'IsDefaultCnst') = 1
I adapted it from Donabel Santos's blog here.
EDIT and NB: Be sure to run both parts of the query and save the second result set (i.e. ADD CONSTRAINTs) before dropping your default constraints, else you won't be able to re-create them again (no I didn't do that :)
A good and free Microsoft tool. You can export the schema and the data.
Microsoft SQL Server Database Publishing Wizard
Try DBSourceTools. http://dbsourcetools.codeplex.com
It has schema compare function that will help you create an update script.
Bear in mind though, that you should be using source-code control on your entire database.
This is what DBSourceTools was designed to do - help developers bring their databases under source control.