Update using right function in Where statement - sql-server

I am trying to update one table from another table using the last 4 digits of a column. Below is what I have that is obviously failing. Using SQL 2012
UPDATE [DB].[dbo].[table1]
SET column1 = (SELECT table2.column1
FROM table2
WHERE (dbo.table2.column2 = dbo.table1.column2)
AND (dbo.table2.column3 = dbo.table1.column3)
AND (dbo.table2.column4 = dbo.table1.column4)
AND (dbo.table2.right(column5,4) = dbo.table1.right(column5,4))

The right way to perform an UPDATE with a JOIN in SQL Server is:
UPDATE t1
SET t1.column1 = t2.column1
FROM [DB].[dbo].[table1] t1
INNER JOIN dbo.table2 t2
ON t2.column2 = t1.column2 COLLATE SQL_Latin1_General_CP1_CI_AS
AND t2.column3 = t1.column3 COLLATE SQL_Latin1_General_CP1_CI_AS
AND t2.column4 = t1.column4 COLLATE SQL_Latin1_General_CP1_CI_AS
AND right(t2.column5,4) = right(t1.column5,4) COLLATE SQL_Latin1_General_CP1_CI_AS;

Related

Issue in procedure (resolve the collation conflict)

I have written a stored procedure like below lines of code
ALTER PROCEDURE [dbo].[pr_AgentLinceseInfo_Fetch]
AS
BEGIN
IF OBJECT_ID('tempdb..#BrList') IS NOT NULL
DROP TABLE #BrList
CREATE TABLE #BrList
(
AgentCode nvarchar(max)
,BrokerName nvarchar(max)
,LicenceID bigint
,LicenceNumber nvarchar(max)
,EffectiveDate datetime
,ExpirationDate datetime
,State nvarchar(max)
);
INSERT INTO #BrList
SELECT
a.AgentCode AS BrokerCode,
sy.BrokerName,
L.Licence, L.LicenceNumber,
DateIssued AS EffectiveDate,
L.ExpirationDate,
J.JurisdictionX AS State
FROM
tbAgent AS a
INNER JOIN
tbLicence L ON L.AgentId = a.Agent
LEFT OUTER JOIN
(SELECT Jurisdiction, JurisdictionX
FROM tbJurisdiction) AS j ON j.Jurisdiction =
(CASE
WHEN ISNULL(L.Jurisdiction, '0') = '0'
THEN a.PhysicalAddressState
ELSE L.Jurisdiction
END)
LEFT OUTER JOIN
(SELECT
SystemUser, (FirstName + ' ' + LastName) AS BrokerName
FROM tbSystemUser) AS sy ON sy.SystemUser = a.SystemUser
SELECT * FROM #BrList
SELECT
t.*, p.ProductX, p.ProductCode
FROM
tbCompanyAgent ca
LEFT OUTER JOIN
(SELECT
AgentCode, BrokerName,
LicenceID, LicenceNumber,
EffectiveDate, ExpirationDate, [State]
FROM #BrList) AS t ON t.LicenceNumber = ca.LicenceNumber
INNER JOIN
tbProduct p ON p.Product = ca.ProductId
DROP TABLE #BrList
END
When we execute this procedure, it throws error message
Cannot resolve the collation conflict
Cannot resolve the collation
conflict between "SQL_Latin1_General_CP1_CI_AS" and
"Latin1_General_CI_AI" in the equal to operation.
The problem is you have two different collations in comparing columns
You should not have two different collation in columns when you want to compare them.
Example:
Consider the following query
SELECT 1
WHERE 'a' COLLATE SQL_Latin1_General_CP1_CI_AS = 'a' COLLATE Latin1_General_CI_AI
Which will throw error stating
Msg 468, Level 16, State 9, Line 1 Cannot resolve the collation
conflict between "Latin1_General_CI_AI" and
"SQL_Latin1_General_CP1_CI_AS" in the equal to operation.
It can resolved by explictly making the collation same in both LHS and RHS
SELECT 1
WHERE 'a' COLLATE SQL_Latin1_General_CP1_CI_AS = 'a' COLLATE SQL_Latin1_General_CP1_CI_AS.
Try updating your query like this
SELECT t.*,
p.ProductX,
p.ProductCode
FROM tbCompanyAgent ca
LEFT OUTER JOIN (SELECT AgentCode,
BrokerName,
LicenceID,
LicenceNumber,
EffectiveDate,
ExpirationDate,
[State]
FROM #BrList) AS t
ON t.LicenceNumber COLLATE SQL_Latin1_General_CP1_CI_AS = ca.LicenceNumber COLLATE SQL_Latin1_General_CP1_CI_AS
INNER JOIN tbProduct p
ON p.Product COLLATE SQL_Latin1_General_CP1_CI_AS = ca.ProductId COLLATE SQL_Latin1_General_CP1_CI_AS
jUST ADD this line -> SQL_Latin1_Generstrong textal_CP1_CI_AS in your joinings. Thats it :)
https://premkt.blogspot.my/2016/12/error-cannot-resolve-collation-conflict.html

Collation issue while join query in MVC5 and SQL Server 2012

When I join two tables I got a collation issue that is
System.Data.SqlClient.SqlException: Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Latin1_General_CI_AI" in the equal to operation.
Then I set the collation in my db using the following code
ALTER DATABASE [CAM] COLLATE SQL_Latin1_General_CP1_CI_AS;
ALTER TABLE CAM_Users
ALTER COLUMN [EmployeeCode] VARCHAR(50)
COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL;
But I still get the same error.
My join query is this:
List<DTOUserManagement> users = (from CAMuser in _unitOfWorkAsync.RepositoryAsync<CAM_Users>().Queryable()
join QRuser in _unitOfWorkAsync.RepositoryAsync<CAM_V_EmployeeMaster>().Queryable() on CAMuser.EmployeeCode equals QRuser.EmployeeCode into t
from t1 in t.DefaultIfEmpty()
join CAMDomain in _unitOfWorkAsync.RepositoryAsync<CAM_Domain>().Queryable() on CAMuser.DomainID equals CAMDomain.DomainID into t2
from t3 in t2.DefaultIfEmpty()
where CAMuser.IsActive
select new DTOUserManagement
{
TransactUserCode = CAMuser.TransactUserCode,
EmployeeCode = CAMuser.EmployeeCode,
EmployeeName = t1.EmployeeName,
Email = t1.EMail,
DomainID = CAMuser.DomainID,
DomainName = t3.DomainName,
IsActive = CAMuser.IsActive,
AssignedRole = CAMuser.AssignedRoles
}).ToList();
How can I solve this?
Please reply anybody
The problem here is that the COLLATION must match on joining columns.
There are two ways to fix this. First you could change the collation on each column. Or second, you can change the collation at execution time. Here's an example of the second approach:
Sample Data
/* T1 and T2 are identical tables in structre and content, except
* for the collation.
*/
DECLARE #T1 TABLE
(
ID VARCHAR(3) COLLATE SQL_Latin1_General_CP1_CI_AS
)
;
DECLARE #T2 TABLE
(
ID VARCHAR(3) COLLATE Latin1_General_CI_AI
)
;
INSERT INTO #T1
(
ID
)
VALUES
('x'),
('y'),
('z')
;
INSERT INTO #T2
(
ID
)
VALUES
('x'),
('y'),
('z')
;
Anti Pattern - Will not Work
/* This query will failed with the error:
* Cannot resolve the collation conflict between "Latin1_General_CI_AI" and "SQL_Latin1_General_CP1_CI_AS" in the equal to operation.
*/
SELECT
*
FROM
#T1 AS t1
INNER JOIN #T2 AS t2 ON t1.ID = t2.ID
;
Corrected - No Error
/* Success.
*/
SELECT
*
FROM
#T1 AS t1
INNER JOIN #T2 AS t2 ON t1.ID = t2.ID COLLATE Latin1_General_CI_AI
;
You need to check your tables that are involved in these JOINs here to verify that all columns involved have the same collation.
You can do this with this SQL query:
SELECT
TableName = t.Name,
ColumnName = c.name,
Collation = c.collation_name
FROM
sys.columns c
INNER JOIN
sys.tables t ON t.object_id = c.object_id
INNER JOIN
sys.types ty ON c.system_type_id = ty.system_type_id
WHERE
t.name IN ('CAM_Users', 'CAM_Domain') -- add any further tables to check
AND ty.name IN ('char', 'nchar', 'nvarchar', 'varchar')
ORDER BY
t.name, c.name
If there are columns that do not match the database default collation, you need to change those to be the same as all other columns. Once all the string columns in those tables are the same collation, then your joins should work.
Update: use this query to find those tables & columns that do not have the current default database collation:
SELECT
TableName = t.Name,
ColumnName = c.name,
Collation = c.collation_name
FROM
sys.columns c
INNER JOIN
sys.tables t ON t.object_id = c.object_id
INNER JOIN
sys.types ty ON c.system_type_id = ty.system_type_id
WHERE
ty.name IN ('char', 'nchar', 'nvarchar', 'varchar')
AND c.collation_name <> 'SQL_Latin1_General_CP1_CI_AS'
ORDER BY
t.name, c.name

Sql Server error [SQLState 42000] (Error 325)

I have a script that utilizes the new Merge Output clause. I've run it in 3 different instances (all non-Production environments) and it works great. When I tried running it in our production environment, I get the error:
Executed as user: xxx\xxx. Incorrect syntax near 'Merge'. You
may need to set the compatibility level of the current database to a
higher value to enable this feature. See help for the SET
COMPATIBILITY_LEVEL option of ALTER DATABASE. [SQLSTATE 42000] (Error
325) Incorrect syntax near 'Merge'. You may need to set the
compatibility level of the current database to a higher value to
enable this feature. See help for the SET COMPATIBILITY_LEVEL option
of ALTER DATABASE. [SQLSTATE 42000] (Error 325). The step failed.
I've checked the versions of each instance and they are all 10.0.4000.0. All of the non-system databases are set to compatibility level 90 (2005), and system databases are set to 100 (2008). What else do I need to check to see where my production instance is different from the other non-Production instances?
Here's the query:
Declare #user varchar(20),
#message varchar(max)
Set #user = 'ISS20120917-144'
Create Table #data
(
CustomerEventID_Surrogate Int Identity (1,1) Not Null Primary Key,
CustomerNumber Int Not Null,
ConvictionEventID Int Not Null,
CustomerEventHierarchyID Int Not Null,
SanctionEventID Int Not Null,
ReferenceNumber varchar(40) Null,
ConvictionACDID Int Null,
State_Code varchar(2) Not Null,
County_ID Int Null,
CitationCDLHolderValueID Int Null,
Hazmat Bit Null,
CMV Bit Null,
PassengerEndorsement Bit Null,
OccurrenceDate DateTime Not Null,
ConvictionDate DateTime Not Null,
CourtOrder Bit Null
)
Create Table #surrogatemap
(
CustomerEventID_Surrogate Int Not Null,
NewCustomerEventID Int Not Null
)
Create Table #surrogateHIDmap
(
NewCustomerEventID Int Not Null,
NewHistoryEventDetailID Int Not Null
)
Begin Tran
Begin Try
Insert Into #data
Select ce.Cust_No,
ce.CustomerEventID,
ceh.CustomerEventHierarchyID,
ceSAN.CustomerEventID,
ce.ReferenceNumber,
hed.ACDID,
hed.State_Code,
hed.County_ID,
hed.CitationCDLHolderValueID,
hed.Hazmat,
hed.CMV,
hed.PassengerEndorsement,
hed.OccurrenceDate,
Case When cd.ConvictionDate IS NOT NULL Then cd.ConvictionDate
Else hed.OccurrenceDate
End As [ConvictionDate],
hed.CourtOrder
From IADS..CustomerEvent ce
Inner Join IADS..HistoryEventDetail hed On hed.CustomerEventID = ce.CustomerEventID
And hed.EndDate IS NULL
Inner Join IADS..CustomerEventCode cec On cec.CustomerEventCodeID = hed.CustomerEventCodeID
And cec.CustomerEventCodeID <> -51
Left Outer Join IADS..ConvictionDetail cd On cd.HistoryEventDetailID = hed.HistoryEventDetailID
Inner Join IADS..CustomerEventHierarchy ceh On ceh.CustomerEventID = ce.CustomerEventID
And ceh.EndDate IS NULL
Inner Join IADS..CustomerEvent ceSAN On ceSAN.CustomerEventID = ceh.RelatedCustomerEventID
And ceSAN.CustomerEventDispositionID IS NULL
Inner Join IADS..CustomerSanctionDetail csd On csd.CustomerEventID = ceSAN.CustomerEventID
And csd.SanctionDiscardedReasonID IS NULL
Inner Join IADS..SanctionReasonCode src On src.SanctionReasonCodeID = csd.SanctionReasonCodeID
And src.SanctionReasonCodeID = -320
Where ce.CustomerEventDispositionID IS NULL
Merge Into IADS..CustomerEvent
Using #data As src On 1 = 0
When Not Matched Then
Insert
(
CustomerEventCategoryID,
Cust_No,
ReferenceNumber,
CreatedBy,
CreatedDate,
UpdatedBy,
UpdatedDate
)
Values
(
-2,
src.CustomerNumber,
src.ReferenceNumber,
#user,
GetDate(),
#user,
GetDate()
)
Output
src.CustomerEventID_Surrogate,
inserted.CustomerEventID
Into #surrogatemap;
Select sm.NewCustomerEventID,
-8 As [HistoryEventTypeID],
-51 As [CustomerEventCodeID],
131 As [ACDID],
d.State_Code,
d.County_ID,
d.CitationCDLHolderValueID,
d.OccurrenceDate,
d.ConvictionDate,
d.Hazmat,
d.CMV,
d.CourtOrder,
GETDATE() As [EffectiveDate],
#user As [UpdatedBy],
GETDATE() As [UpdatedDate],
d.ConvictionACDID,
d.PassengerEndorsement
Into #hiddata
From #data d
Inner Join #surrogatemap sm On sm.CustomerEventID_Surrogate = d.CustomerEventID_Surrogate
Merge Into IADS..HistoryEventDetail
Using #hiddata As src On 1 = 0
When Not Matched Then
Insert
(
CustomerEventID,
HistoryEventTypeID,
CustomerEventCodeID,
ACDID,
State_Code,
County_ID,
CitationCDLHolderValueID,
OccurrenceDate,
Hazmat,
CMV,
CourtOrder,
EffectiveDate,
UpdatedBy,
UpdatedDate,
UnderlyingACDID,
PassengerEndorsement
)
Values
(
src.NewCustomerEventID,
src.HistoryEventTypeID,
src.CustomerEventCodeID,
src.ACDID,
src.State_Code,
src.County_ID,
src.CitationCDLHolderValueID,
src.OccurrenceDate,
src.Hazmat,
src.CMV,
src.CourtOrder,
src.EffectiveDate,
src.UpdatedBy,
src.UpdatedDate,
src.ConvictionACDID,
src.PassengerEndorsement
)
Output
src.NewCustomerEventID,
inserted.HistoryEventDetailID
Into #surrogateHIDmap;
Insert Into IADS..CustomerEventHierarchy
(
CustomerEventID,
RelatedCustomerEventID,
EffectiveDate,
UpdatedBy,
UpdatedDate
)
Select sm.NewCustomerEventID,
d.SanctionEventID,
GETDATE(),
#user,
GETDATE()
From #data d
Inner Join #surrogatemap sm On sm.CustomerEventID_Surrogate = d.CustomerEventID_Surrogate
Insert Into IADS..CourtFineDetail
(
HistoryEventDetailID,
ConvictionDate
)
Select s.NewHistoryEventDetailID,
d.ConvictionDate
From #hiddata d
Inner Join #surrogateHIDmap s On s.NewCustomerEventID = d.NewCustomerEventID
-- Remove the tie to the SUS077
Update IADS..CustomerEventHierarchy
Set EndDate = GETDATE(),
UpdatedBy = #user,
UpdatedDate = GETDATE()
Where CustomerEventHierarchyID In (Select CustomerEventHierarchyID From #data)
-- Build temp table containing the records that have already purged
Select ce.Cust_No,
ce.CustomerEventID,
ceh.CustomerEventHierarchyID
Into #disposedRecords
From IADS..CustomerEvent ce
Inner Join IADS..HistoryEventDetail hed On hed.CustomerEventID = ce.CustomerEventID
And hed.EndDate IS NULL
Inner Join IADS..CustomerEventCode cec On cec.CustomerEventCodeID = hed.CustomerEventCodeID
And hed.CustomerEventCodeID <> -51
Inner Join IADS..CustomerEventHierarchy ceh On ceh.CustomerEventID = ce.CustomerEventID
And ceh.EndDate IS NULL
Inner Join IADS..CustomerEvent ceSAN On ceSAN.CustomerEventID = ceh.RelatedCustomerEventID
And ceSAN.CustomerEventDispositionID IS NOT NULL
Inner Join IADS..CustomerSanctionDetail csd On csd.CustomerEventID = ceSAN.CustomerEventID
And csd.SanctionReasonCodeID = -320
Where ce.CustomerEventDispositionID IS NOT NULL
Order By ce.CustomerEventDispositionDate Desc
-- Un-purge all of the records that were previously tied to a SUS077
Update IADS..CustomerEvent
Set CustomerEventDispositionID = Null,
CustomerEventDispositionComment = Null,
CustomerEventDispositionDate = Null,
UpdatedBy = #user,
UpdatedDate = GETDATE()
Where CustomerEventID In (Select CustomerEventID From #disposedRecords)
-- Remove the records from the PURGEEventsReadyForPurge table
Delete
From IADS..PURGEEventsReadyForPurge
Where CustomerEventID In (Select CustomerEventID From #disposedRecords)
-- Remove tie of purged records
Update IADS..CustomerEventHierarchy
Set EndDate = GETDATE(),
UpdatedBy = #user,
UpdatedDate = GETDATE()
Where CustomerEventHierarchyID In (Select CustomerEventHierarchyID From #disposedRecords)
Delete From IADS..PURGEEventsReadyForPurge Where PURGEEventsReadyForPurgeID In
(
Select PURGEEventsReadyForPurgeID
From IADS..PURGEEventsReadyForPurge p
Inner Join IADS..CustomerEvent ce On ce.CustomerEventID = p.CustomerEventID
And ce.CustomerEventDispositionID IS NULL
Inner Join IADS..CustomerEventCategory ceg On ceg.CustomerEventCategoryID = ce.CustomerEventCategoryID
Left Outer Join IADS..CustomerEventHierarchy ceh On ceh.CustomerEventID = ce.CustomerEventID
Left Outer Join IADS..CustomerEventHierarchy ceh2 On ceh2.RelatedCustomerEventID = ce.CustomerEventID
Where p.PurgeDate IS NOT NULL
)
Drop Table #disposedRecords
Drop Table #hiddata
Drop Table #surrogateHIDmap
Drop Table #surrogatemap
Drop Table #data
Commit
End Try
Begin Catch
Drop Table #disposedRecords
Drop Table #hiddata
Drop Table #surrogateHIDmap
Drop Table #surrogatemap
Drop Table #data
Rollback
End Catch
You can try any of these two things..
1. Update the compatiability level to 100.
ALTER DATABASE [dbname] SET COMPATIBILITY_LEVEL = 100
2. End the MERGE statement and the statement previous to MERGE with a semicolon (;)
Hope it works.

Implicit conversion of varchar value to varchar - collation conflict

I'm getting the following error whilst running this script. I've tried using the following:
COLLATE Latin1_General_CI_AS. Please can it be sorted? Thanks
Msg 457, Level 16, State 1, Line 8
Implicit conversion of varchar value to varchar cannot be performed because the collation of the value is unresolved due to a collation conflict
DECLARE #AccountID INT
SET #AccountID = 12
SELECT TOP 1 ac.AccountID,
co.Email,
ao.AccountOptionID
FROM CRM.acc.Account ac
INNER JOIN CRM.[profile].[Profile] pr
ON pr.ProfileID = ac.ProfileFK
INNER JOIN CRM.[profile].Contact co
ON pr.ProfileID = co.ProfileFK
LEFT JOIN CRM.acc.[AccountOption] ao
ON ao.AccountFK = ac.AccountID
LEFT JOIN (
SELECT OptionID
FROM CRM.acc.[Option]
WHERE [Name] = 'SMS messages') op
ON op.OptionID = ao.OptionFK
WHERE ac.AccountID = #AccountID
UNION ALL
SELECT u.UnsubscribeID,
u.EmailAddress,
u.SentEmailFK
FROM Email.dbo.Unsubscribe u
INNER JOIN (
SELECT CASE
WHEN AccountTypeFK = 2 THEN OnlineBillingEmail
ELSE EmailBillingEmail
END [EmailAddress]
FROM CRM.acc.Account
WHERE AccountID = #AccountID
) ace
ON ace.EmailAddress COLLATE DATABASE_DEFAULT = u.EmailAddress COLLATE DATABASE_DEFAULT
WHERE ISNULL(ace.EmailAddress, '') != ''
Seems that you have different collation types on your database. Then you can have issues when joining tables or to tables in other databases, as in this case. To get around this you can specify the collation of columns or force a collation using the COLLATE clause when joining two columns. Check more info about collation in MSDN
Also you need to specify the COLLATE clause where you are using the problematic column(s). Check this answer, it answer a very similar question
It is better to stick to a single collation globally. Otherwise you will have problems.
See a detailed explanation of the different collation styles
Edited: to check column collation use this snippet
SELECT name, collation_name
FROM sys.columns
WHERE OBJECT_ID IN (SELECT OBJECT_ID
FROM sys.objects
WHERE type = 'U'
AND name = 'your_table_name'
)
AND name = 'your_column_name'
Edited: added snippet to get all columns with different collation on a database
SELECT [TABLE_NAME] = OBJECT_NAME([id]),
[COLUMN_NAME] = [name],
[COLLATION_NAME] = collation
FROM syscolumns
WHERE collation <> 'your_database_collation_type'
AND collation IS NOT NULL
AND OBJECTPROPERTY([id], N'IsUserTable')=1
try this
ace.EmailAddress COLLATE Latin1_General_CI_AS = u.EmailAddress COLLATE Latin1_General_CI_AS
Because you are doing a union all to the CRM table which has a different collation. You need to explicitly define the collation of your columns going into your union. In your case that will be UnsubscribeID,EmailAddress and SentEmailFK all should be defined with collate database_default
Running the below should work. Let me know in the comments if this works
SELECT TOP 1 ac.AccountID,
co.Email,
ao.AccountOptionID
FROM CRM.acc.Account ac
INNER JOIN CRM.[profile].[Profile] pr
ON pr.ProfileID = ac.ProfileFK
INNER JOIN CRM.[profile].Contact co
ON pr.ProfileID = co.ProfileFK
LEFT JOIN CRM.acc.[AccountOption] ao
ON ao.AccountFK = ac.AccountID
LEFT JOIN (
SELECT OptionID
FROM CRM.acc.[Option]
WHERE [Name] = 'SMS messages') op
ON op.OptionID = ao.OptionFK
WHERE ac.AccountID = #AccountID
UNION ALL
SELECT u.UnsubscribeID COLLATE DATABASE_DEFAULT AS UnsubscribeID,
u.EmailAddress COLLATE DATABASE_DEFAULT AS EmailAddress ,
u.SentEmailFK COLLATE DATABASE_DEFAULT AS SentEmailFK
FROM Email.dbo.Unsubscribe u
INNER JOIN (
SELECT CASE
WHEN AccountTypeFK = 2 THEN OnlineBillingEmail
ELSE EmailBillingEmail
END [EmailAddress]
FROM CRM.acc.Account
WHERE AccountID = #AccountID
) ace
ON ace.EmailAddress COLLATE DATABASE_DEFAULT = u.EmailAddress COLLATE
DATABASE_DEFAULT
WHERE ISNULL(ace.EmailAddress, '') != ''

Retrieve column descriptions from SQL Server-linked table in MS Access

I am linking to tables in SQL Server from an MS Access front-end. There are column descriptions for some of the tables in SQL Server that I would like to bring forward when I create the linked tables in Access. Is there a way to get at the column descriptions programmatically?
(I know how to append the description to the linked tables, I just need help getting at the descriptions in the back end.)
Try something like:
DECLARE #TableName varchar(100)
SELECT #TableName = 'yourtablename'
-- This will determine if we're using version 9 (2005) of SQL Server, and execute code accordingly
IF CAST(REPLACE(SUBSTRING(CAST(SERVERPROPERTY('productversion') as varchar),1,2), '.','') as int) >= 9
BEGIN
-- This is a SQL 2005 machine
SELECT
[Table Name] = OBJECT_NAME(c.object_id),
[Column Name] = c.name,
[Description] = ex.value
FROM
sys.columns c
LEFT OUTER JOIN
sys.extended_properties ex
ON
ex.major_id = c.object_id
AND ex.minor_id = c.column_id
AND ex.name = 'MS_Description'
WHERE
OBJECTPROPERTY(c.object_id, 'IsMsShipped')=0
AND OBJECT_NAME(c.object_id) = #TableName
ORDER
BY OBJECT_NAME(c.object_id), c.column_id
END
ELSE
BEGIN
-- assume this is a SQL 2000
SELECT
[Table Name] = i_s.TABLE_NAME,
[Column Name] = i_s.COLUMN_NAME,
[Description] = s.value
FROM
INFORMATION_SCHEMA.COLUMNS i_s
LEFT OUTER JOIN
sysproperties s
ON
s.id = OBJECT_ID(i_s.TABLE_SCHEMA+'.'+i_s.TABLE_NAME)
AND s.smallid = i_s.ORDINAL_POSITION
AND s.name = 'MS_Description'
WHERE
OBJECTPROPERTY(OBJECT_ID(i_s.TABLE_SCHEMA+'.'+i_s.TABLE_NAME), 'IsMsShipped')=0
AND i_s.TABLE_NAME = #TableName
ORDER BY
i_s.TABLE_NAME, i_s.ORDINAL_POSITION
END

Resources