sql server - ऑपरेशन के बराबर में "SQL_Latin1_General_CP1_CI_AS" और "लैटिन 1_General_CI_AS" के बीच संयोजन संघर्ष को हल नहीं कर सकता




sql-server (13)

@ वाल्कीरी कमाल का जवाब। मैंने सोचा कि एक सबक्वायरी के साथ ऐसा करने पर मैंने एक मामला दर्ज किया है, एक संग्रहीत प्रक्रिया में शामिल है, क्योंकि मुझे आश्चर्य हुआ कि आपका जवाब इस मामले में काम करता है, और यह बहुत अच्छा था।

...WHERE fieldname COLLATE DATABASE_DEFAULT in ( select distinct otherfieldname COLLATE DATABASE_DEFAULT from ... where ... )

मेरे पास निम्न कोड है

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

कोड चलाते समय मुझे तालिका सी के लिए दो जुड़ने के बाद शीर्षक में चिपकाई गई त्रुटि मिल रही है। मुझे लगता है कि इस तथ्य के साथ कुछ ऐसा हो सकता है जो मैं SQL Server 2008 का उपयोग कर रहा हूं और इस डीबी की एक प्रति को पुनर्स्थापित कर दिया है मेरी मशीन जो 2005 है।


Marc_s के जवाब के लिए धन्यवाद मैंने अपनी मूल समस्या हल की - इसे एक कदम आगे ले जाने के लिए प्रेरित किया और एक समय में एक पूरी तालिका को बदलने के लिए एक दृष्टिकोण पोस्ट किया - tsql स्क्रिप्ट बदलने के लिए कॉलम कथन उत्पन्न करने के लिए:

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)

हो जाता है: वैकल्पिक तालिका संबद्ध वैकल्पिक कॉलम myTable NVARCHAR (4000) COLLATE लैटिन 1_General_CI_AS न्यूल नहीं

मैं col.max_length / 2 की आवश्यकता से परेशान होने के लिए स्वीकार करूंगा -


आप अपनी मेज में दो अलग-अलग collations का एक मेल नहीं है। आप इस क्वेरी का उपयोग कर अपनी तालिका में प्रत्येक कॉलम में कौन से कॉलम की जांच कर सकते हैं:

SELECT
    col.name, col.collation_name
FROM 
    sys.columns col
WHERE
    object_id = OBJECT_ID('YourTableName')

तारों की व्यवस्था और तुलना करते समय कोलेशन की आवश्यकता होती है और उपयोग किया जाता है। आम तौर पर आपके डेटाबेस में उपयोग किए जाने वाले एकल, अद्वितीय संयोजन का एक अच्छा विचार है - एक टेबल या डेटाबेस के भीतर अलग-अलग कॉलेशन का उपयोग न करें - आप केवल परेशानी के लिए पूछ रहे हैं ....

एक बार जब आप एक एकल collation के लिए बस गए हैं, तो आप उन तालिकाओं / कॉलम को बदल सकते हैं जो इस आदेश का उपयोग करके अभी तक मेल नहीं खाते हैं:

ALTER TABLE YourTableName
  ALTER COLUMN OffendingColumn
    VARCHAR(100) COLLATE Latin1_General_CI_AS NOT NULL

न घुलनेवाली तलछट

अद्यतन: अपने डेटाबेस में पूर्ण टेक्स्ट सूचकांक ढूंढने के लिए, यहां इस क्वेरी का उपयोग करें:

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

फिर आप फुलटेक्स्ट इंडेक्स का उपयोग कर ड्रॉप कर सकते हैं:

DROP FULLTEXT INDEX ON (tablename)

आप आसानी से 4 आसान चरणों का उपयोग कर ऐसा कर सकते हैं

  1. अपने डेटाबेस का बैकअप लें, बस परेशान करें
  2. डेटाबेस संयोजन बदलें: डेटाबेस पर राइट क्लिक करें, गुणों का चयन करें, विकल्पों पर जाएं और आवश्यक कोलेक्शन में संयोजन बदलें।
  3. अपनी सभी डेटाबेस ऑब्जेक्ट्स को ड्रॉप और मनोरंजन करने के लिए एक स्क्रिप्ट जेनरेट करें: अपने डेटाबेस पर राइट क्लिक करें, कार्यों का चयन करें, स्क्रिप्ट जेनरेट करें ... (सुनिश्चित करें कि आप विज़ार्ड के उन्नत विकल्पों पर ड्रॉप और बनाएं चुनें, स्कीमा और डेटा भी चुनें)
  4. ऊपर उत्पन्न स्क्रिप्ट चलाएं

उन लोगों के लिए जिनके पास डेटाबेस के लिए एक डाटाबेस स्क्रिप्ट (जैसा मेरा मामला था) है, जो इस समस्या का कारण बन रहे हैं, आप कोलेक्शन से मेल खाने के लिए निम्न CREATE स्क्रिप्ट का उपयोग कर सकते हैं:

-- 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

या

-- 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

यह सभी तालिकाओं के लिए वांछित संयोजन लागू होता है, जो कि मुझे बस चाहिए था। यह सर्वर पर सभी डेटाबेस के लिए संयोजन को समान रखने और रखने के लिए आदर्श है। उम्मीद है की यह मदद करेगा।

निम्न लिंक पर अधिक जानकारी: एसक्यूएल सर्वर - सर्वर पर विभिन्न संयोजन के साथ डेटाबेस बनाना


त्रुटि (बीच के बीच संयोजन संयोजन को हल नहीं कर सकता ....) आमतौर पर कई डेटाबेस से डेटा की तुलना करते समय होता है।

चूंकि आप अब डेटाबेस के संयोजन को नहीं बदल सकते हैं, COLATATE DATABASE_DEFAULT का उपयोग करें।

----------
AND db1.tbl1.fiel1 COLLATE DATABASE_DEFAULT =db2.tbl2.field2 COLLATE DATABASE_DEFAULT 

मूल कारण यह है कि आपने जिस स्क्वायर सर्वर डेटाबेस से स्कीमा लिया है वह एक संयोजन है जो आपके स्थानीय स्थापना से अलग है। यदि आप collation के बारे में चिंता नहीं करना चाहते हैं तो SQL सर्वर 2008 डेटाबेस के रूप में एक ही संयोजन का उपयोग करके स्थानीय रूप से SQL सर्वर स्थापित करें।


मेरे पास पहले ऐसा कुछ था, और हमने जो पाया वह था कि 2 टेबल के बीच संयोजन अलग था।

जांचें कि ये वही हैं।


मैंने निम्न स्क्रिप्ट बनाने के लिए इस site से सामग्री का उपयोग किया है जो सभी तालिकाओं में सभी स्तंभों के संयोजन को बदलता है:

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

यदि यह आपके पूरे डीबी में होता है तो अपने डीबी संयोजन को बदलना बेहतर होता है:

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 

here संदर्भ


यहां हमने जो किया है, हमारी स्थिति में हमें मांग पर दिनांक प्रतिबंध का उपयोग करके निष्पादित करने के लिए एक विज्ञापन की आवश्यकता है, और क्वेरी को तालिका में परिभाषित किया गया है।

हमारी नई क्वेरी को विभिन्न डेटाबेस के बीच डेटा मिलान करने और उनमें से दोनों डेटा शामिल करने की आवश्यकता है।

ऐसा लगता है कि COLBATION डीबी के बीच अलग है जो iSeries / AS400 सिस्टम से डेटा आयात करता है, और हमारे रिपोर्टिंग डेटाबेस - यह विशिष्ट डेटा प्रकारों (जैसे नामों पर यूनानी उच्चारण और अन्य) के कारण हो सकता है।

तो हमने नीचे शामिल खंड का उपयोग किया:

...LEFT Outer join ImportDB..C4CTP C4 on C4.C4CTP COLLATE Latin1_General_CS_AS=CUS_Type COLLATE Latin1_General_CS_AS

वैकल्पिक डेटाबेस परीक्षण 2 - अपना डेटाबेस नाम यहां COLLATE लैटिन 1_General_CS_AS रखें - आपको जो भी संयोजन चाहिए उसे प्रतिस्थापित करें


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 )