PDA

View Full Version : تغییر Collation در اشکال در دستورات؟



SYNDROME
یک شنبه 01 آذر 1388, 06:44 صبح
با سلام
با استفاده از دستور


SELECT *
FROM INFORMATION_SCHEMA.TABLES


می خواهم لیست جداول بانک خودم را در یک جدول موقت در Tempdb بریزم.
ولی سیستم می گوید باید Collation بانک خود را از Arabic_CI_AS به Arabic_CI_AI تغییر بدهی تا بتوانی لیست جداول را در یک جدول موقت در بانک Tempdb بریزی.
اگر این تغییر را انجام دهم این عملیات انجام می شود ولی یک اتفاق می افتد.
دستور




SELECT *


FROM INFORMATION_SCHEMA.Column

دیگر کار نمی کند و پیغام می دهد چنین دستوری معتبر نیست در صورتی که قبل ار تغییر Collation درست کار می کند و باید دستور را حتما به شکل






SELECT *


FROM INFORMATION_SCHEMA.COLUMN


نوشته شود(باید با حروف بزرگ باشد)تا کار کند.
1:چرا باید من Collation را تغییر دهیم؟
2:آیا راه حلی است که بدون تغییر Collationاین اتفاق بیفتد؟
3:چرا بعد از تغییر Collation چنین اتفاقی می افتد؟
ممنون می شود مانند گذشته به سوال من جواب دهید.
با تشکر فراوان

Reza.ariyan
یک شنبه 01 آذر 1388, 15:55 عصر
تو بعضی محاسبات اگه Collation لاتین باشه و یا مناسب نباشه SQL قاتی میکنه و درست محاسبات رو انجام نمیده - مثل جست و جو های شرط دار

SELECT * FROM TABLE1 WHERE NAME="حسنی"

اینجا حرف ی(ی)
------------
دلیل اینکه این مشکل برای شما پیش اومده اینه که COLLATION جدول های شما هماهنگ نیست
مثلا یکی PERSIAN_100.... و دیگری COLLATION پیشفرض یا لاتین
برای حل این مشکل میتونید یکی از کارهای زیر رو بکنید
1 . ساختار کل بانک رو از نو بسازید با COLLATION دلخواه
2 . اسکریپت زیر رو اجرا کنید که COLLATION همه جداول رو به COLLATION بانک تغییر بده



DECLARE @defaultCollation NVARCHAR(1000)
SET @defaultCollation=CAST(DATABASEPROPERTYEX(DB_NAME( ) , 'Collation') AS NVARCHAR(1000))

DECLARE @ColumnName NVARCHAR(1000)
DECLARE @TableName NVARCHAR(1000)
DECLARE @CollationName NVARCHAR(1000)
DECLARE @STRSQL NVARCHAR(1000)
DECLARE crs CURSOR
FOR (SELECT Information_Schema.Columns.Table_Name , Column_Name ,
CAST(DATABASEPROPERTYEX(DB_NAME() , 'Collation') AS NVARCHAR(1000)) CollationName
FROM Information_Schema.Columns
INNER JOIN Information_Schema.Tables ON Information_Schema.Columns.Table_Name=Information_ Schema.Tables.Table_Name
WHERE Information_Schema.Tables.Table_Type='Base Table'
AND RTRIM(LTRIM(Collation_Name))<>RTRIM(LTRIM(CAST(DATABASEPROPERTYEX(DB_NAME() , 'Collation') AS NVARCHAR(1000))))
AND COLUMNPROPERTY(OBJECT_ID(Information_Schema.Column s.Table_Name) ,
Column_Name , 'IsComputed')=0)
OPEN crs
FETCH FROM crs INTO @TableName , @ColumnName,@CollationName
WHILE @@FETCH_STATUS=0
BEGIN

SET @STRSQL='ALTER TABLE '+@TableName+' ALTER COLUMN '+@ColumnName
FETCH NEXT FROM crs INTO @TableName , @ColumnName,@CollationName
END

هنوز ناقصه - تا چند دقیقه دیگه تکمیلش میکنم

SYNDROME
یک شنبه 01 آذر 1388, 16:09 عصر
با تشکر
1-بهترین گزینه برای Collation بانک که قرار است حروف فارسی و انگلیسی را ذخیره کند کدام گزینه است؟؟؟؟
2-چطور می توانم تفاوت Collation بانک خودم و Tempdb خود SQL را بر طرف کنم؟
3-اگرهر Collation یک سری تنظیمات دارداز کجا می توانی منبعی به دست آورم که توضیحات لازم را داده باشد؟؟؟
منتظر راهنمایی دوستان هستم

Reza.ariyan
یک شنبه 01 آذر 1388, 18:18 عصر
نتونستم کاملش کنم
میزارم اگه تونستی کامل کن



DECLARE @ColumnName NVARCHAR(1000)
DECLARE @TableName NVARCHAR(1000)
DECLARE @DataType NVARCHAR(1000)
DECLARE @DefaultCollation NVARCHAR(1000)
DECLARE @STRSQL NVARCHAR(1000)
DECLARE @is_nullable BIT
SET @DefaultCollation=CAST(DATABASEPROPERTYEX(DB_NAME( ) , 'Collation') AS NVARCHAR(1000))
DECLARE crs CURSOR
FOR (SELECT sys.tables.name AS TableName , sys.columns.name AS ColumnName ,
sys.columns.is_nullable , sys.types.name AS DataType
FROM sys.columns
INNER JOIN sys.tables ON sys.columns.object_id=sys.tables.object_id
INNER JOIN sys.types ON sys.columns.user_type_id=sys.types.user_type_id
WHERE sys.columns.collation_name<>@DefaultCollation)
OPEN crs
FETCH FROM crs INTO @TableName , @ColumnName , @is_nullable , @DataType
WHILE @@FETCH_STATUS=0
BEGIN
IF @is_nullable=0
BEGIN
SET @STRSQL='ALTER TABLE ['+@TableName+'] ALTER COLUMN ['
+@ColumnName+'] '+@DataType+' COLLATE '+@DefaultCollation
+' null'
END
ELSE
BEGIN
SET @STRSQL='ALTER TABLE ['+@TableName+'] ALTER COLUMN ['
+@ColumnName+']'+@DataType+' COLLATE '+@DefaultCollation
+' not null'
END
PRINT @STRSQL
EXECUTE (@STRSQL)
FETCH NEXT FROM crs INTO @TableName , @ColumnName , @is_nullable ,
@DataType
END
CLOSE crs
DEALLOCATE crs


ولی با کد پایینی میتونی ببینی که چه فیلد هایی دارای Colation ناهماهنگ با دیتابیست هستن و اوونارو Alter کنی



SELECT sys.tables.name AS TableName , sys.columns.name AS ColumnName ,
sys.columns.is_nullable , sys.types.name AS DataType
FROM sys.columns
INNER JOIN sys.tables ON sys.columns.object_id=sys.tables.object_id
INNER JOIN sys.types ON sys.columns.user_type_id=sys.types.user_type_id
WHERE sys.columns.collation_name<>@DefaultCollation

AminSobati
یک شنبه 01 آذر 1388, 23:17 عصر
سلام دوست عزیزم،
لطفا دقیقا دستوری که باهاش نام جدول رو به tempdb انتقال میدین پست کنید

Reza.ariyan
دوشنبه 02 آذر 1388, 00:22 صبح
سلام دوست عزیزم،
لطفا دقیقا دستوری که باهاش نام جدول رو به tempdb انتقال میدین پست کنید
به tempdb کاری ندارم
فقط همه فیلد هایی رو که Collation اوونها نا مساوی Collation دیتابیس هست رو پیدا میکنم و بعد Alter میکنم و بعد Collation اوونهارو تغییر میدم(به این صورت که STRING دستور رو تو کرسر درست میکنم و بعد این STRING رو Execute میکنم) به این ترتیب Collation همه فیلد ها درست میشه ...
تنها کاری که باید کنید که کامل بشه اینه که DataType هایی که از نوع NVARCHAR یا Varchar و یا هر نوع داده که نیاز به طول رشته داره رو ویرایش کنید و به جای اینکه STRING ما اینطوری باشه :



SET @STRSQL='ALTER TABLE ['+@TableName+'] ALTER COLUMN ['
+@ColumnName+'] '+@DataType+' COLLATE '+@DefaultCollation
+' null'


باید اینطوری بشه



SET @STRSQL='ALTER TABLE ['+@TableName+'] ALTER COLUMN ['
+@ColumnName+'] '+@DataType+'('+@MAXLENGTH+') COLLATE '+@DefaultCollation
+' null'


یه راهنمایی اینکه MaxLenght تو SystemTable مربوط به Columns هست (sys.columns یا sys.AllColumns)

خروجی اولی میشه این که باید اجرا بشه

ALTER TABLE [Table1] ALTER COLUMN [Testcolumn] VARCHAR COLLATE PERSIAN_100_CI_AS

که به خاطر اینکه محدوده VARCHAR مشخص نشده خطا میده
---
ولی کد دومی خروجیش این میشه که باید EXECUTE بشه

ALTER TABLE [Table1] ALTER COLUMN [Testcolumn] VARCHAR(50) COLLATE PERSIAN_100_CI_AS


که گفتم MAXLENGHTH تو SYS.COLUMNS که JOIN کردم هست
*****ولی یه نکته******
برای فیلد های از نوع INTERNATIONAL که اولشون N داره مثل : NVARCHAR , NCHAR و .... مقدار MAXLENGHTH ای که تو جدول SYS.COLUMNS ثبت میشه همیشه دوبرابر ثبت میشه
مثلا اگه (NVARCHAR(50 باشه تو SYS.COLUMNS مقدار MAXLENGHTH رو میزنه 100
ولی برای VARCHAR و همه انواع ascii مقدار درست save میشه
مثلا اگه (VARCHAR(50 باشه تو SYS.COLUMNS مقدار MAXLENGHTH رو میزنه 50

AminSobati
دوشنبه 02 آذر 1388, 08:21 صبح
به tempdb کاری ندارم
فقط همه فیلد هایی رو که Collation اوونها نا مساوی Collation دیتابیس هست رو پیدا میکنم و بعد...


البته دستوری که پست اول به اون اشاره داره منظورم هست

misoft.ir
دوشنبه 02 آذر 1388, 21:54 عصر
با تشکر
1-بهترین گزینه برای Collation بانک که قرار است حروف فارسی و انگلیسی را ذخیره کند کدام گزینه است؟؟؟؟

این سوال من هم هست

AminSobati
دوشنبه 02 آذر 1388, 22:55 عصر
Collation ارتباطی به ذخیره حروف فارسی یا انگلیسی نداره. شما با داشتن فیلد nvarchar میتونین هر اطلاعاتی ذخیره کنید. تاثیر Collation در Sorting و انواع Sensitivity هست

SYNDROME
چهارشنبه 04 آذر 1388, 12:58 عصر
Collation ارتباطی به ذخیره حروف فارسی یا انگلیسی نداره. شما با داشتن فیلد nvarchar میتونین هر اطلاعاتی ذخیره کنید. تاثیر Collation در Sorting و انواع Sensitivity هست
با سلام
اگر امکان دارد در مورد Collation ها کمی بیشتر توضیح دهید.
که چطور باید Collation مناسب را انتخاب کرد.
با تشکر

SYNDROME
یک شنبه 18 بهمن 1388, 07:36 صبح
با سلام
می خواستم بدانم تفاوت SQL_Latin_General_CPI_CI_AS با Arabic_CI_AS در چیست؟
ممنون می شوم بنده را راهنمایی کنید.
با تشکر

AminSobati
یک شنبه 18 بهمن 1388, 08:35 صبح
سلام دوست عزیزم،
همه Collationها ممکنه روی زبان مورد نظر ما متفاوت رفتار نکنند. مثلا دو Collationی که مثال زدین شاید روی Sort اطلاعات فارسی یکسان عمل کنند ولی قطعا Arabic و Persian متفاوت هستند

SYNDROME
یک شنبه 18 بهمن 1388, 10:14 صبح
سلام دوست عزیزم،
همه Collationها ممکنه روی زبان مورد نظر ما متفاوت رفتار نکنند. مثلا دو Collationی که مثال زدین شاید روی Sort اطلاعات فارسی یکسان عمل کنند ولی قطعا Arabic و Persian متفاوت هستند
با تشکر از دوست گرامی
امین جان من دو تا جدول رو از دو تا بانک متفاوت با Collection متفاوت با هم Join می زنم.


Select *
From Bank1.dbo.Tbl_Test T1
Join INFORMATION_SCHEMA.COLUMNS T2
On T1.Name = T2.Name

ولی خطا می دهد.
Colection یکی Arabic_CI_AI و دیگری Arabic_CS_AI است.
مشکل از کجاست؟؟؟
با تشکر از دوستان

AminSobati
دوشنبه 19 بهمن 1388, 19:55 عصر
میتونین موقع Join تبدیل کنین:

select * from t1 join t2 on t1.name collate arabic_ci_ai=t2.name

SYNDROME
چهارشنبه 21 بهمن 1388, 15:20 عصر
با سلام
ممنون از جوابتان آقا امین
می خواستم بدانم زمانی که یک DataBase یک Collation داره و SQL با یک Collation دیگر نصب شده باشد در هنگام Sort و . . . Collation کدام یک ملاک انجام عملیات است؟
با تشکر

AminSobati
چهارشنبه 21 بهمن 1388, 17:46 عصر
زمانی که SQL Server نصب میشه، در حقیقت Default Server Collation رو انتخاب میکنین. به این معنی که اگر در هنگام ساخت دیتابیس، Collation رو معرفی نکردین، از Server به ارث میبره. ولی اگر مشخص کنین، همه کارها طبق همین Collation اتفاق خواهد افتاد