PDA

View Full Version : Membership و Roles (فوری)



manager
دوشنبه 21 فروردین 1385, 14:40 عصر
سلام

دوستان من واقعا از دست این مشکل خسته شدم...دیگه نمی دونم باید چی کار کنم .. لطفا منو راهنمائی کنید.:گریه:

من تو Asp.net 2 از Membership و Roles استفاده کردم و با ابزار aspnet_regsql جداول و مواد مورد نیاز MembershipProviders و ... رو (همه رو) در دیتابیس خودم ایجاد کردم..

اما هر چند وقت یه بار با خطائی مواجه می شم که می گه;

Cannot resolve collation conflict for equal to operation.


>> در ضمن من به صورت دستی از درستی و صحت و جامعیت اطلاعات در دیتابیسم مطمئن هستم... همچنین این خطا از SP به نام aspnet_Roles_AddUserToRole ایجاد می شه !! حتی دستورات این SP رو تجزیه و تحلیل کردم تا به یه سری دستورات داخل این SP رسیدم (تقریبا اواسط برنامه) که خطا از اونجا ناشی می شد ...

باور کنید من نزدیک یکی دو هفته است با این مشکل دست و پنجه نرم می کنم ... ولی شکست خوردم ..

جالبی این قضیه اینجاست که اگر از همین بانک یه Backup بگیرم و ببرم تو یه PC دیگه و Restore کنم کار می کنه ولی اگر تو یه سیستم این خطا رو بگیرم دیگه به هیچ عنوان درست نمی شه !!!!!!!!

لطفا کمکم کنید آبروم در خطره !!!! :گریه: :اشتباه:

nazaninam
دوشنبه 21 فروردین 1385, 22:33 عصر
فقط باسه همدردی با شما من هم این مشکل رو بعضی وقتا پیدا می کنم به شکل خیلی مسخره ای رفع میشه .... خدا صبر بده...

anubis_ir
سه شنبه 22 فروردین 1385, 08:47 صبح
Cannot resolve collation conflict for equal to operation.
این مورد به collation مربوط میشه. (تقریبا میشه گفت زبان پیش فرض فیلد یا دیتابیس. اگر هنگام انجام مقایسه، این دو یکی نباشند این خطا داده می‌شود.)
برای حل این مشکل باید collation به صراحت پس از نام فیلد ذکر شود. برای مثال:

tbl1.t1 = tbl2.f2 COLLATE Latin1_General_CI_AS

manager
سه شنبه 22 فروردین 1385, 13:16 عصر
Cannot resolve collation conflict for equal to operation.
این مورد به collation مربوط میشه. (تقریبا میشه گفت زبان پیش فرض فیلد یا دیتابیس. اگر هنگام انجام مقایسه، این دو یکی نباشند این خطا داده می‌شود.)
برای حل این مشکل باید collation به صراحت پس از نام فیلد ذکر شود. برای مثال:

tbl1.t1 = tbl2.f2 COLLATE Latin1_General_CI_AS


kheyli mamnoon...

agar mishe jenab ye kam bishtar toozih bedin mamnoon misham...

to ro khoda komakam konid abroye chandin salam dar khatareh....

manager
سه شنبه 22 فروردین 1385, 21:26 عصر
احسن به شما آقای(خانم) anubis_ir :تشویق:

مشکلم رفع شد و هزار بار از شما تشکر می کنم :بوس:

manager
سه شنبه 22 فروردین 1385, 21:30 عصر
اگر لطف کنید راجه به Collate بیشتر توضیح بدین ممنون می شم..

Behrouz_Rad
سه شنبه 22 فروردین 1385, 21:53 عصر
توضیحات تکمیلی:
این خطا در زمان عدم تطبیقCollate دیتابیس tempdb با دیتابیس مربوطه رخ میده!
و معمولا برای داده های نوع VarChar امکان رخ دادن بیشتری داره.
با اجرای دستور زیر می تونید از Collate دیتابیس مطلع بشید:


EXEC sp_helpdb 'myDBName'

Collate، خاصیتی از دیتابیس است که زبان مقایسه داده های جدول را مشخص می کند.

موفق باشید.

nokhod
شنبه 21 بهمن 1385, 13:44 عصر
منم به همین مشکل بر خوردم!!! الانم که دارم این متن رو می نویسم از کلافگی نمی دونم چه کار کنم. هر چی زور زدم که درستش کنم نشد که نشد!

یکی لطف کنه و به من هم بگه که چطوری حل میشه. خیلی قاطی کردم.

خیلی خیلی ممنون.

manager
دوشنبه 23 بهمن 1385, 12:24 عصر
اگر به صحبت های سایر دوستان توجه کنید..می بینید که راه حل این مشکل را تشریح کرده اند.

hamed_bostan
چهارشنبه 01 فروردین 1386, 09:22 صبح
با سلام .
1- من در هنگام اجرای اسکریپت ساختدیتابیسم باید collate دیتابیس روی سیستم خودم رو بنویسم و مشخص کنم یا collate سرور رو؟
2- در هنگام ساخت دیتابیسم collate اون برابر server default بوده و الان وقتی از دیتابیسم prpoerty می گیرم جلوی collate خالی هست و چیزی نشون نداده
ممنون

کدم رو به این تغییر دادم :





CREATE PROCEDURE dbo.aspnet_UsersInRoles_AddUsersToRoles
@ApplicationName nvarchar(256),
@UserNames nvarchar(4000),
@RoleNames nvarchar(4000),
@CurrentTimeUtc datetime
AS
BEGIN
DECLARE @AppId uniqueidentifier
SELECT @AppId = NULL
SELECT @AppId = ApplicationId FROM aspnet_Applications WHERE LOWER(@ApplicationName) = LoweredApplicationName
IF (@AppId IS NULL)
RETURN(2)
DECLARE @TranStarted bit
SET @TranStarted = 0

IF( @@TRANCOUNT = 0 )
BEGIN
BEGIN TRANSACTION
SET @TranStarted = 1
END

DECLARE @tbNames table(Name nvarchar(256) COLLATE Arabic_CI_AS NOT NULL PRIMARY KEY)
DECLARE @tbRoles table(RoleId uniqueidentifier COLLATE Arabic_CI_AS NOT NULL PRIMARY KEY)
DECLARE @tbUsers table(UserId uniqueidentifier COLLATE Arabic_CI_AS NOT NULL PRIMARY KEY)
DECLARE @Num int
DECLARE @Pos int
DECLARE @NextPos int
DECLARE @Name nvarchar(256)

SET @Num = 0
SET @Pos = 1
WHILE(@Pos <= LEN(@RoleNames))
BEGIN
SELECT @NextPos = CHARINDEX(N',', @RoleNames, @Pos)
IF (@NextPos = 0 OR @NextPos IS NULL)
SELECT @NextPos = LEN(@RoleNames) + 1
SELECT @Name = RTRIM(LTRIM(SUBSTRING(@RoleNames, @Pos, @NextPos - @Pos)))
SELECT @Pos = @NextPos+1

INSERT INTO @tbNames VALUES (@Name)
SET @Num = @Num + 1
END

INSERT INTO @tbRoles
SELECT RoleId
FROM dbo.aspnet_Roles ar, @tbNames t
WHERE LOWER(t.Name) = ar.LoweredRoleName AND ar.ApplicationId = @AppId

IF (@@ROWCOUNT <> @Num)
BEGIN
SELECT TOP 1 Name
FROM @tbNames
WHERE LOWER(Name) NOT IN (SELECT ar.LoweredRoleName FROM dbo.aspnet_Roles ar, @tbRoles r WHERE r.RoleId = ar.RoleId)
IF( @TranStarted = 1 )
ROLLBACK TRANSACTION
RETURN(2)
END

DELETE FROM @tbNames WHERE 1=1
SET @Num = 0
SET @Pos = 1

WHILE(@Pos <= LEN(@UserNames))
BEGIN
SELECT @NextPos = CHARINDEX(N',', @UserNames, @Pos)
IF (@NextPos = 0 OR @NextPos IS NULL)
SELECT @NextPos = LEN(@UserNames) + 1
SELECT @Name = RTRIM(LTRIM(SUBSTRING(@UserNames, @Pos, @NextPos - @Pos)))
SELECT @Pos = @NextPos+1

INSERT INTO @tbNames VALUES (@Name)
SET @Num = @Num + 1
END

INSERT INTO @tbUsers
SELECT UserId
FROM dbo.aspnet_Users ar, @tbNames t
WHERE LOWER(t.Name) = ar.LoweredUserName AND ar.ApplicationId = @AppId

IF (@@ROWCOUNT <> @Num)
BEGIN
DELETE FROM @tbNames
WHERE LOWER(Name) IN (SELECT LoweredUserName FROM dbo.aspnet_Users au, @tbUsers u WHERE au.UserId = u.UserId)

INSERT dbo.aspnet_Users (ApplicationId, UserId, UserName, LoweredUserName, IsAnonymous, LastActivityDate)
SELECT @AppId, NEWID(), Name, LOWER(Name), 0, @CurrentTimeUtc
FROM @tbNames

INSERT INTO @tbUsers
SELECT UserId
FROM dbo.aspnet_Users au, @tbNames t
WHERE LOWER(t.Name) = au.LoweredUserName AND au.ApplicationId = @AppId
END

IF (EXISTS (SELECT * FROM dbo.aspnet_UsersInRoles ur, @tbUsers tu, @tbRoles tr WHERE tu.UserId = ur.UserId AND tr.RoleId = ur.RoleId))
BEGIN
SELECT TOP 1 UserName, RoleName
FROM dbo.aspnet_UsersInRoles ur, @tbUsers tu, @tbRoles tr, aspnet_Users u, aspnet_Roles r
WHERE u.UserId = tu.UserId AND r.RoleId = tr.RoleId AND tu.UserId = ur.UserId AND tr.RoleId = ur.RoleId

IF( @TranStarted = 1 )
ROLLBACK TRANSACTION
RETURN(3)
END

INSERT INTO dbo.aspnet_UsersInRoles (UserId, RoleId)
SELECT UserId, RoleId
FROM @tbUsers, @tbRoles

IF( @TranStarted = 1 )
COMMIT TRANSACTION
RETURN(0)
END
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO



اما این ایراد رو میگیره :




Cannot add rows to sysdepends for the current stored procedure because it depends on the missing object 'dbo.aspnet_Users_CreateUser'. The stored procedure will still be created.
Cannot add rows to sysdepends for the current stored procedure because it depends on the missing object 'dbo.aspnet_Personalization_GetApplicationId'. The stored procedure will still be created.
Cannot add rows to sysdepends for the current stored procedure because it depends on the missing object 'dbo.aspnet_Personalization_GetApplicationId'. The stored procedure will still be created.
Cannot add rows to sysdepends for the current stored procedure because it depends on the missing object 'dbo.aspnet_Personalization_GetApplicationId'. The stored procedure will still be created.
Cannot add rows to sysdepends for the current stored procedure because it depends on the missing object 'dbo.aspnet_Personalization_GetApplicationId'. The stored procedure will still be created.
Cannot add rows to sysdepends for the current stored procedure because it depends on the missing object 'dbo.aspnet_Personalization_GetApplicationId'. The stored procedure will still be created.
Cannot add rows to sysdepends for the current stored procedure because it depends on the missing object 'dbo.aspnet_Personalization_GetApplicationId'. The stored procedure will still be created.
Cannot add rows to sysdepends for the current stored procedure because it depends on the missing object 'dbo.aspnet_Personalization_GetApplicationId'. The stored procedure will still be created.
Cannot add rows to sysdepends for the current stored procedure because it depends on the missing object 'dbo.aspnet_Personalization_GetApplicationId'. The stored procedure will still be created.
Cannot add rows to sysdepends for the current stored procedure because it depends on the missing object 'dbo.aspnet_Personalization_GetApplicationId'. The stored procedure will still be created.
Cannot add rows to sysdepends for the current stored procedure because it depends on the missing object 'dbo.aspnet_Users_CreateUser'. The stored procedure will still be created.
Cannot add rows to sysdepends for the current stored procedure because it depends on the missing object 'dbo.aspnet_Users_DeleteUser'. The stored procedure will still be created.
Cannot add rows to sysdepends for the current stored procedure because it depends on the missing object 'dbo.aspnet_Users_CreateUser'. The stored procedure will still be created.
Server: Msg 447, Level 16, State 1, Procedure aspnet_UsersInRoles_AddUsersToRoles, Line 25
Expression type uniqueidentifier is invalid for COLLATE clause.
Server: Msg 447, Level 16, State 1, Procedure aspnet_UsersInRoles_RemoveUsersFromRoles, Line 26
Expression type uniqueidentifier is invalid for COLLATE clause.

manager
چهارشنبه 01 فروردین 1386, 10:23 صبح
خوب من چند تا SP مربوط به Roles رو ویرایش کردم و مشکل عدم هماهنگی Collact رو از بین بردم. خیلی جالبه که مایکروسافت این باگ رو تو سیستم Membership خودش جا گذاشته. البته اصلا جای تعجب نداره، مایکروسافته دیگه !!!!!!!!

SP هائی که باید ویرایش کنید عبارتند از :
aspnet_UsersInRoles_AddUsersToRoles
aspnet_UsersInRoles_RemoveUsersFromRolesو به عنوان نمونه :




CREATE PROCEDURE dbo.aspnet_UsersInRoles_AddUsersToRoles
..

INSERT INTO @tbRoles
SELECT RoleId
FROM dbo.aspnet_Roles ar , @tbNames t
WHERE LOWER(t.Name) = ar.LoweredRoleName COLLATE Latin1_General_CI_AS AND ar.ApplicationId = @AppId

... FROM @tbNames
WHERE LOWER(Name) COLLATE Latin1_General_CI_AS NOT IN (SELECT ar.LoweredRoleName FROM dbo.aspnet_Roles ar, @tbRoles r WHERE r.RoleId =
...
return(0)
END
GO

hamed_bostan
چهارشنبه 01 فروردین 1386, 10:56 صبح
ممنون از راهنماییتون .
من توی script نویسی اصلا مهارت ندارم و جز حاهایی که گفتین نمی دونم کجا ها دیگه باید این کد رو اضافه کنم . ممکنه شما یه عیدی به ما بدین؟
اگه ممکنه شما که script این جداول رو درست کردین و جواب گرفتین درستش رو بذارین اینجا ما هم استفاده کنیم؟

ممنون

manager
چهارشنبه 01 فروردین 1386, 13:37 عصر
من توی script نویسی اصلا مهارت ندارم و جز حاهایی که گفتین نمی دونم کجا ها دیگه باید این کد رو اضافه کنم . ممکنه شما یه عیدی به ما بدین؟من اینجا از همه کوچیکترم، شما باید بهم عیدی بدید.

hamed_bostan
چهارشنبه 01 فروردین 1386, 13:50 عصر
من یه سوال دیگه هم بپرسم و دیگه اذیتت نکنم .
بهترین collate واسه ماها که فارسی تو سیستممون ذخیره سازی میکنیم چیه؟

manager
چهارشنبه 01 فروردین 1386, 14:36 عصر
والا این سوال دیگه می ره تو بخش Sql Server ولی من همیشه از Default دیتا بیس استفاده کردم مشکلی نداره (SQL_Latin1_General_CP1_CI_AS )،

زیرا :
1- یک Collation Unicode هست و فارسی رو به خوبی پشتیبانی می کنه
2- دقدقه ی عدم هماهنگی برای مقایسه و درج و ... نداره
3- سربار اضافی برای تطبیق و تبدیل Collate ها برای SQL Server ایجاد نمی کنه

البته ناگفته نمونه که دیتاتایپ های شما باید Unicode باشند مثل : nText, nvarchar و یا nchar. هنگامی که از این دیتا تایپ ها استفاده می کنید دیگه

SQL Server داده ها را به کد پیج مربوط به Collate نبدیل نمی کنه و به صورت Unicode ذخیره می کنه و این مطلب سربار اضافی را از دوش پردازنده SQL

Server بر می داره.
نکته ی دیگه ای که باید بهش توجه کرد اینه که اگر دیتابیس شما دارای Collate خاصی باشه، وقتی با TempDB کار می کنید باید مراقب تبدیلات Collate

باشید تا SQL Server خطا نگیره.
ولی شما می تونید مثلا از Windows Collate با نام Arabic_BIN یا Arabic_CI_AC و یا SQL Collate با نام SQL_Latin1_General_CP1256_CI_AS استفاده

کنید که مخصوص فارسی و همون نتایج بالا رو بهتون می ده ولی دردسر سازه یک، دو اینکه باز هم با این Collate ها باید از Data Type ها Unicode استفاده کنید.

hamed_bostan
چهارشنبه 01 فروردین 1386, 15:58 عصر
راستی در مورد profile هم ما همین مشکل رو داریم بابت collation؟

sinaone1
سه شنبه 03 آذر 1388, 22:57 عصر
ممنون از لطف شما ( خیلی ) کامل جواب داد برای این که دوستان بی بهره نمونند این کد زیر کامل به من جواب داد امیدوارم به شما هم جواب بده :

CREATE PROCEDURE [dbo].[aspnet_UsersInRoles_AddUsersToRoles]
@ApplicationName nvarchar(256),
@UserNames nvarchar(4000),
@RoleNames nvarchar(4000),
@CurrentTimeUtc datetime
AS
BEGIN
DECLARE @AppId uniqueidentifier
SELECT @AppId = NULL
SELECT @AppId = ApplicationId FROM aspnet_Applications WHERE LOWER(@ApplicationName) COLLATE Latin1_General_CI_AS = LoweredApplicationName COLLATE Latin1_General_CI_AS
IF (@AppId IS NULL)
RETURN(2)
DECLARE @TranStarted bit
SET @TranStarted = 0

IF( @@TRANCOUNT = 0 )
BEGIN
BEGIN TRANSACTION
SET @TranStarted = 1
END

DECLARE @tbNames table(Name nvarchar(256) COLLATE database_default NOT NULL PRIMARY KEY)
DECLARE @tbRoles table(RoleId uniqueidentifier NOT NULL PRIMARY KEY)
DECLARE @tbUsers table(UserId uniqueidentifier NOT NULL PRIMARY KEY)
DECLARE @Num int
DECLARE @Pos int
DECLARE @NextPos int
DECLARE @Name nvarchar(256)

SET @Num = 0
SET @Pos = 1
WHILE(@Pos <= LEN(@RoleNames))
BEGIN
SELECT @NextPos = CHARINDEX(N',', @RoleNames, @Pos)
IF (@NextPos = 0 OR @NextPos IS NULL)
SELECT @NextPos = LEN(@RoleNames) + 1
SELECT @Name = RTRIM(LTRIM(SUBSTRING(@RoleNames, @Pos, @NextPos - @Pos)))
SELECT @Pos = @NextPos+1

INSERT INTO @tbNames VALUES (@Name)
SET @Num = @Num + 1
END

INSERT INTO @tbRoles
SELECT RoleId
FROM dbo.aspnet_Roles ar, @tbNames t
WHERE LOWER(t.Name) COLLATE Latin1_General_CI_AS= ar.LoweredRoleName COLLATE Latin1_General_CI_AS AND ar.ApplicationId = @AppId

IF (@@ROWCOUNT <> @Num)
BEGIN
SELECT TOP 1 Name
FROM @tbNames
WHERE LOWER(Name)COLLATE Latin1_General_CI_AS NOT IN (SELECT ar.LoweredRoleName COLLATE Latin1_General_CI_AS FROM dbo.aspnet_Roles ar, @tbRoles r WHERE r.RoleId = ar.RoleId)
IF( @TranStarted = 1 )
ROLLBACK TRANSACTION
RETURN(2)
END

DELETE FROM @tbNames WHERE 1=1
SET @Num = 0
SET @Pos = 1

WHILE(@Pos <= LEN(@UserNames))
BEGIN
SELECT @NextPos = CHARINDEX(N',', @UserNames, @Pos)
IF (@NextPos = 0 OR @NextPos IS NULL)
SELECT @NextPos = LEN(@UserNames) + 1
SELECT @Name = RTRIM(LTRIM(SUBSTRING(@UserNames, @Pos, @NextPos - @Pos)))
SELECT @Pos = @NextPos+1

INSERT INTO @tbNames VALUES (@Name)
SET @Num = @Num + 1
END

INSERT INTO @tbUsers
SELECT UserId
FROM dbo.aspnet_Users ar, @tbNames t
WHERE LOWER(t.Name) COLLATE Latin1_General_CI_AS = ar.LoweredUserName COLLATE Latin1_General_CI_AS AND ar.ApplicationId = @AppId

IF (@@ROWCOUNT <> @Num)
BEGIN
DELETE FROM @tbNames
WHERE LOWER(Name) COLLATE Latin1_General_CI_AS IN (SELECT LoweredUserName COLLATE Latin1_General_CI_AS FROM dbo.aspnet_Users au, @tbUsers u WHERE au.UserId = u.UserId)

INSERT dbo.aspnet_Users (ApplicationId, UserId, UserName, LoweredUserName , IsAnonymous, LastActivityDate)
SELECT @AppId, NEWID(), Name, LOWER(Name) COLLATE Latin1_General_CI_AS, 0, @CurrentTimeUtc
FROM @tbNames

INSERT INTO @tbUsers
SELECT UserId
FROM dbo.aspnet_Users au, @tbNames t
WHERE LOWER(t.Name)COLLATE Latin1_General_CI_AS = au.LoweredUserName COLLATE Latin1_General_CI_AS AND au.ApplicationId = @AppId
END

IF (EXISTS (SELECT * FROM dbo.aspnet_UsersInRoles ur, @tbUsers tu, @tbRoles tr WHERE tu.UserId = ur.UserId AND tr.RoleId = ur.RoleId))
BEGIN
SELECT TOP 1 UserName, RoleName
FROM dbo.aspnet_UsersInRoles ur, @tbUsers tu, @tbRoles tr, aspnet_Users u, aspnet_Roles r
WHERE u.UserId = tu.UserId AND r.RoleId = tr.RoleId AND tu.UserId = ur.UserId AND tr.RoleId = ur.RoleId

IF( @TranStarted = 1 )
ROLLBACK TRANSACTION
RETURN(3)
END

INSERT INTO dbo.aspnet_UsersInRoles (UserId, RoleId)
SELECT UserId, RoleId
FROM @tbUsers, @tbRoles

IF( @TranStarted = 1 )
COMMIT TRANSACTION
RETURN(0)
END