2010-09-27 7 views
6

Ich habe immer die Nachricht "Kann den Kollationskonflikt zwischen" SQL_Latin1_General_CP1_CI_AS "und" Latin1_General_CI_AI "in der Gleichheitsoperation nicht lösen." wenn ich das Skript ausführen, das von MSSQL 2005 Server kam. btw i verwendet MSSQL 2008.Collation Conflict

Hier ist das Skript

USE [database1] 
GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
--exec rsp_SOA '', '', '', '', '', '', '40050000', '40050000', '05/01/2010', '05/31/2010', '000-00','Dont Show Note' 

ALTER procedure [dbo].[rsp_SOA] 
    @cCompName VARCHAR(100) , 
    @cAddress1 VARCHAR(200) , 
    @cAddress2 VARCHAR(200), 
    @cReportTitle VARCHAR(200), 
    @cCriteria1 VARCHAR(200), 
    @cCriteria VARCHAR(200), 

    @cFrom VARCHAR(25), 
    @cTo VARCHAR(25), 
    @dDateFrom VARCHAR(10), 
    @dDateTo VARCHAR(10), 
    @cCompID VARCHAR(10), 
    @cFilter VARCHAR(30) 
as 

declare @cSQL VARCHAR(200), 
     @cSQL1 VARCHAR(200), 
     @cmd VARCHAR(8000), 
     @cmd1 VARCHAR(8000), 
     @cTempTable varchar (50), 
     @cTempTable1 varchar (50), 
     @nInterval VARCHAR(3), 
     @nCurrent INTEGER, 
     @nInterval1 varchar(3), 
     @nInterval2 varchar(3), 
     @nInterval3 varchar(3), 
     @nInterval4 varchar(3), 
     @nInterval5 varchar(3), 
     @dd INTEGER, 
     @cValue1 VARCHAR(100), 
     @cValue2 VARCHAR(100), 
     @cValue3 VARCHAR(100), 
     @cValue4 VARCHAR(100), 
     @cValue5 VARCHAR(100) 

set @nInterval = 30 
set @nInterval1 = cast(@nInterval * 1 as varchar(3)) 
set @nInterval2 = cast(@nInterval * 2 as varchar(3)) 
set @nInterval3 = cast(@nInterval * 3 as varchar(3)) 
set @nInterval4 = cast(@nInterval * 4 as varchar(3)) 
set @nInterval5 = cast(@nInterval * 5 as varchar(3)) 

SET @cValue1 = CONVERT(VARCHAR(10),1,110) + ' - ' + CONVERT(VARCHAR(10),@nInterval1,110) + ' Days' 
SET @cValue2 = CONVERT(VARCHAR(10),@nInterval1 + 1,110) + ' - ' + CONVERT(VARCHAR(10),@nInterval2,110) + ' Days' 
SET @cValue3 = CONVERT(VARCHAR(10),@nInterval2 + 1,110) + ' - ' + CONVERT(VARCHAR(10),@nInterval3,110) + ' Days' 
SET @cValue4 = CONVERT(VARCHAR(10),@nInterval3 + 1,110) + ' - ' + CONVERT(VARCHAR(10),@nInterval4,110) + ' Days' 
SET @cValue5 = 'Above ' + CONVERT(VARCHAR(10),@nInterval4,110) + ' Days' 

create table ##Interval 
(
    cCompID varchar(20), 
    nOrder int, 
    cInterval varchar(20), 
    cCode varchar(20) 
) 


--------------------------- 
--get all the clients 
--------------------------- 
SELECT * INTO ##temp1 FROM 
(
    select cCode from client_customer where cCode = @cFrom union all 
    select cGroupCode from client_customer where cCode = @cFrom union all 
    select cBillingCompany from client_customer where cCode = @cFrom union all 
    select cArea from client_customer where cCode = @cFrom 
)a 

--------------------------- 
--determining the balance of the invoices 
--------------------------- 
SELECT * INTO ##temp2 FROM 
(
    (
     select a.cCompanyID, a.cInvNo, sum(a.nGross) as nSales, 0 as nPaid, 0 as nDebit, 0 as nCredit, 0 as nReturns 
     from sales a 
     where a.lCancelled = 0 and a.cPayType<>'Cash' 
      and a.cCode in (select * FROM ##temp1) --get all the clients 
      and a.cCompanyID = @cCompID 
     group by a.cCompanyID, a.cInvNo 
    ) 
    union all 
    (
     select a.cCompanyID, a.cInvNo, 0 as nSales, sum(a.nApplied) as nPaid, 0 as nDebit, 0 as nCredit, 0 as nReturns 
     from pr_t a 
     left outer join pr b on a.cTranNo = b.cTranNo and a.cCompanyID = b.cCompanyID 
     left outer join sales c on a.cInvNo = c.cInvNo and a.cCompanyID = c.cCompanyID 
     where b.lCancelled = 0 
      and c.cCode in (select * FROM ##temp1) --get all the clients 
      and a.cCompanyID = @cCompID 
     group by a.cCompanyID, a.cInvNo 
    ) 
    union all 
    (
     select a.cCompanyID, a.cInvNo, 0 as nSales, 0 as nPaid, sum(a.nDebit) as nDebit, 0 as nCredit, 0 as nReturns 
     from ar_t a 
     left outer join ar b on a.cTranNo = b.cTranNo and a.cCompanyID = b.cCompanyID 
     where b.cType = 'Debit' and b.lCancelled = 0 and b.lApproved = 1 
      and b.cCode in (select * FROM ##temp1) --get all the clients 
      and a.cCompanyID = @cCompID 
     group by a.cCompanyID, a.cInvNo 
    ) 
    union all 
    (
     select a.cCompanyID, a.cInvNo, 0 as nSales, 0 as nPaid, 0 as nDebit, sum(a.nCredit) as nCredit, 0 as nReturns 
     from ar_t a 
     left outer join ar b on a.cTranNo = b.cTranNo and a.cCompanyID = b.cCompanyID 
     where b.cType = 'Credit' and b.lSalesReturn = 0 and b.lCancelled = 0 and b.lApproved = 1 
      and b.cCode in (select * FROM ##temp1) --get all the clients 
      and a.cCompanyID = @cCompID 
     group by a.cCompanyID, a.cInvNo 
    ) 
    union all 
    (
     select a.cCompanyID, a.cInvNo, 
     0 as nSales, 0 as nPaid, 0 as nDebit, 0 as nCredit, sum(a.nCredit) as nReturns 
     from ar_t a 
     left outer join ar b on a.cTranNo = b.cTranNo and a.cCompanyID = b.cCompanyID 
     where b.cType = 'Credit' and b.lSalesReturn = 1 and b.lCancelled = 0 and b.lApproved = 1 
      and b.cCode in (select * FROM ##temp1) --get all the clients 
      and a.cCompanyID = @cCompID 
     group by a.cCompanyID, a.cInvNo 
    ) 
)a 


----------------------- 
--main script for creating the temp ##AR 
----------------------- 
select a.*, b.cRefNo, b.dRefDate, b.nBeg, b.nEnd, b.nConsumed, b.nConsumedKG, b.nPrice, b.nAmount, b.nVat, b.nWHT, b.nNet, 
      case when a.nDue <=0 then 'Current' 
       when a.nDue > 0 and a.nDue <= @nInterval1 then @cValue1 
       when a.nDue > @nInterval1 and a.nDue <= @nInterval2 then @cValue2 
       when a.nDue > @nInterval2 and a.nDue <= @nInterval3 then @cValue3 
       when a.nDue > @nInterval3 and a.nDue <= @nInterval4 then @cValue4 
       when a.nDue > @nInterval4 then @cValue5 
      end as cInterval,b.cTenantName into ##AR 
    from 
    (
     select a.cCompanyID, b.cCode, a.cInvNo, (isnull(sum(a.nSales), 0) - isnull(sum(a.nPaid), 0) + isnull(sum(a.nDebit), 0) - isnull(sum(a.nCredit), 0) - isnull(sum(a.nReturns), 0)) as nBalance, 
       b.dDate, b.cSMan, b.nGross, b.cTerm, c.cValue, (cast((cast(convert(varchar(20),getdate(),101) as datetime) - b.dDate) as integer) - cast(c.cValue as integer)) as nDue, dateadd(d,cast(c.cValue as integer),b.dDate) as dDueDate 
     from 
     (
      select * FROM ##temp2 --determining the balance of the invoices 
     ) a 
     left outer join sales b on a.cInvNo = b.cInvNo and a.cCompanyID = b.cCompanyID 
     left outer join parameter_user c on b.cTerm = c.cParamName and c.cType = 'TERMS' 
     where b.cCode in (select * FROM ##temp1) --get all the clients 
      and a.cCompanyID = @cCompID 
     group by a.cCompanyID, b.cCode, a.cInvNo, b.dDate, b.cSMan, b.nGross, b.cTerm, c.cValue 
     having (isnull(sum(a.nSales), 0) - isnull(sum(a.nPaid), 0) + isnull(sum(a.nDebit), 0) - isnull(sum(a.nCredit), 0) - isnull(sum(a.nReturns), 0)) > 0 
    )a 
    left outer join 
    (
     select a.cCompanyID, a.cInvNo, b.cRefNo, d.dDate as dRefDate, 
      case when a.cType = 'Meter' then b.nMeterIn 
       when a.cType = 'Weight' then b.nWeightOut 
      else 0 end as nBeg, 
      case when a.cType = 'Meter' then b.nMeterOut 
       when a.cType = 'Weight' then b.nWeightIn 
      else 0 end as nEnd, b.nConsumed, 
      case when a.cType = 'Meter' then b.nConsumedKG 
       when a.cType = 'Weight' then (b.nWeightOut - b.nWeightIn) 
      else 0 end as nConsumedKG, b.nPrice, (b.nAmount/1.12) as nAmount, 
       (b.nAmount - (b.nAmount/1.12)) as nVat, 
       (CASE WHEN e.lEWT=1 THEN ((b.nAmount/1.12) * e.nEWT/100) ELSE 0 END) as nWHT, b.nAmount as nNet,f.cTenantName 


     from sales a left outer join sales_t b on a.cInvNo = b.cInvNo and a.cCompanyID = b.cCompanyID 
      left outer join item c on b.cItemNo = c.cItemNo and a.cCompanyID = c.cCompanyID 
      left outer join dr d on d.cDRNo = b.cRefNo 
      left outer JOIN CLIENT_CUSTOMER e ON a.cCode = e.cCode 
      left outer JOIN METER_READING_T f ON b.cMRNo = f.cTransNo AND b.nMeterIn = f.nMeterIn 
     where c.cType <> 'CYLINDER' and a.cType <> 'Invoice' and a.cCode in (select * FROM ##temp1) --get all the clients 
      and a.cCompanyID = @cCompID 

     union all 

     select a.cCompanyID, a.cInvNo, d.cDRNo as cRefNo, d.dDate as dRefDate, 0 as nBeg, 
      0 as nEnd, b.nConsumed, 0 as nConsumedKG, b.nPrice, b.nAmount, 0 as nVat, 0 as nWHT, 0 as nNet,'' as cTenantName 
     from sales a left outer join sales_t b on a.cInvNo = b.cInvNo and a.cCompanyID = b.cCompanyID 
      left outer join item c on b.cItemNo = c.cItemNo and a.cCompanyID = c.cCompanyID 
      left outer join dr d on a.cInvNo = d.cInvNo   
     where c.cType <> 'CYLINDER' and a.cType = 'Invoice' and d.cDRNo is null and a.cCode in (select * FROM ##temp1) --get all the clients 
      and a.cCompanyID = @cCompID 
    )b on a.cInvNo = b.cInvNo and a.cCompanyID = b.cCompanyID 


----------------------- 
--main script for creating the temp ##Interval 
----------------------- 
insert into ##Interval 
select distinct @cCompID, 1, 'Above 120 Days', cCode from ##AR 
insert into ##Interval 
select distinct @cCompID, 2, '91 - 120 Days', cCode from ##AR 
insert into ##Interval 
select distinct @cCompID, 3, '61 - 90 Days', cCode from ##AR 
insert into ##Interval 
select distinct @cCompID, 4, '31 - 60 Days', cCode from ##AR 
insert into ##Interval 
select distinct @cCompID, 5, '1 - 30 Days', cCode from ##AR 
insert into ##Interval 
select distinct @cCompID, 6, 'Current', cCode from ##AR 




-------------------------------------- 
--displaying the result 
-------------------------------------- 

select a.nOrder, a.cInterval, a.cCode, c.cName, (c.cFirstName + ' ' + case when isnull(c.cMiddleInitial,'')='' then '' else c.cMiddleInitial + ' ' end + c.cLastName) as cCustomerName, (case when isnull(c.cBusinessName,'')='' then c.cName else c.cBusinessName end) as cBusinessName, 
     c.cAddress, c.cLastName, c.cJobTitle, d.cCompanyName, d.cAddress1, d.cAddress2, d.cPhone, d.cfax, d.cEmail, c.cTerm, b.cInvNo, b.nBalance, b.dDate, b.nGross, b.cRefNo, b.dRefDate, b.nBeg, b.nEnd, b.nConsumed, b.nCOnsumedKG, 
     b.nPrice, b.nAmount, b.nVat, b.nWHT, b.nNet, isnull(e.nTotalPDC,0) as nTotalPDC, f.nTotalAR, f.nTotalPastDue, c.nLimit, @dDateFrom as dStartDate, @dDateTo as dEndDate,--g.cTenantName, 
     b.cTenantName,(CASE WHEN @cFilter = 'Show Note' THEN 1 ELSE 0 END) AS lNote 
from ##Interval a 
left outer join ##AR b on a.cInterval = b.cInterval and a.cCode = b.cCode 
left outer join client_customer c on a.cCode = c.cCode 
left outer join company d on a.cCompID = d.cCompanyID 
left outer join 
(
    select a.cCode, sum(a.nAmount) as nTotalPDC 
    from checks a 
    where a.lDeposited=0 and a.cTransType = 'COL' and a.cCode = @cFrom and a.cCompanyID = @cCompID 
    group by a.cCode 
)e on a.cCode=e.cCode 
left outer join 
(
    --select a.cCode, sum(a.nBalance) as nTotalAR, sum(case when a.cInterval <> 'Current' then isnull(a.nBalance,0) else 0 end) as nTotalPastDue 
    --from ##AR a 
    --group by a.cCode 

    SELECT a.cCode,SUM(nTotalAR) AS nTotalAR,SUM(nTotalPastDue) AS nTotalPastDue 
    FROM 
     (select distinct a.cCode, (a.nBalance) as nTotalAR, 
      (case when a.cInterval <> 'Current' then isnull(a.nBalance,0) else 0 end) as nTotalPastDue 
     from ##AR a) a 
    GROUP BY a.cCode 

)f on a.cCode=f.cCode 
order by a.nOrder, a.cCode 


drop table ##temp1 
drop table ##temp2 
drop table ##Interval 
drop table ##AR 


/* 
    select * from ##temp1 
    select * from ##temp2 
    select * from ##Interval 
    select * from ##AR 
*/ 

der SQL Server immer zeigen den Fehler zu dieser Linie

-------------------------------------- 
--displaying the result 
-------------------------------------- 

select a.nOrder, a.cInterval, a.cCode, c.cName, (c.cFirstName + ' ' + case when isnull(c.cMiddleInitial,'')='' then '' else c.cMiddleInitial + ' ' end + c.cLastName) as cCustomerName, (case when isnull(c.cBusinessName,'')='' then c.cName else c.cBusinessName end) as cBusinessName, 
     c.cAddress, c.cLastName, c.cJobTitle, d.cCompanyName, d.cAddress1, d.cAddress2, d.cPhone, d.cfax, d.cEmail, c.cTerm, b.cInvNo, b.nBalance, b.dDate, b.nGross, b.cRefNo, b.dRefDate, b.nBeg, b.nEnd, b.nConsumed, b.nCOnsumedKG, 
     b.nPrice, b.nAmount, b.nVat, b.nWHT, b.nNet, isnull(e.nTotalPDC,0) as nTotalPDC, f.nTotalAR, f.nTotalPastDue, c.nLimit, @dDateFrom as dStartDate, @dDateTo as dEndDate,--g.cTenantName, 
     b.cTenantName,(CASE WHEN @cFilter = 'Show Note' THEN 1 ELSE 0 END) AS lNote 
+1

Wie sieht Ihr Skript aus? – LittleBobbyTables

+0

Also welche Aussage macht das eigentlich Fehler? Und welche Spalte in Ihren Tabellen hat die akzentsensitive Sortierung, und welche hat die eine unempfindlich? Wie lautet die Standardsortierung Ihrer Datenbank und welche ist die Ihres Servers? –

Antwort

4

Es ist wahrscheinlich entweder:

  1. Es sind einige spezifische zeichenartige Spalten oder Tabellen, die mit einer anderen COLLATION erstellt wurden, dann machst du eine Compa Rison auf Spalten unterschiedlicher Sortierung.

  2. Sie führen ein Skript für eine Datenbank mit einer anderen Sortierung als Ihren Server aus, und das Skript verwendet TEMP TABLEs. Temp-Tabellen werden in der Tempdb-Datenbank erstellt, daher erhalten sie die COLLATION von Tempdb (dh die Server-Kollatierung). Die meisten Skripte erwarten dies nicht, so dass Vergleiche mit temporären Tabellenspalten keine Sortierung angeben.

Sie können dieses Problem beheben, entweder durch Ihre Tabellen/Spalten, so dass die Sortierungen Spiel, oder das Ändern Ihrer SQL zu ändern, so dass Sie in jedem String-Vergleich zu verwenden die Sortierung spezifizieren.

z.B. dies ändern:

select * 
from someTable 
inner join #t on someTable.col1 = #t.col1 
where #t.col2 = 'blah' collate database default 

dazu:

select * 
from someTable 
inner join #t on someTable.col1 = #t.col1 collate database default 
where #t.col2 = 'blah' collate database default 

UPDATE:

Basierend auf dem Skript, das Sie geschrieben haben, würde ich denke, es über meinen zweiten Vorschlag ist.

SQL Server sagt das Problem ist in Ihrer letzten massiven Abfrage. Ich schlage vor, einen oder mehrere der folgenden Optionen:

  • Um die bestimmte Abfrage zu identifizieren, die ein Problem Ich würde vorschlagen, dass Sie die Subqueries ausbrechen und haben das Skript sie separat auszuführen. Nur zum Debuggen.

  • Versuchen Sie, sp_help '##temp1' und für die anderen Tabellen aufzurufen, nachdem sie erstellt wurden, und vergleichen Sie die Spaltensortierungen mit denen in Ihren Haupttabellen.

  • collate database default bis zum Ende jeder Ihrer Vergleiche hinzufügen (wo, wenn Sie den Sp_help Vorschlag verwenden erforderlich)

  • explizit stattdessen Ihre temporäre Tabellen erstellen von über SELECT INTO. Auf diese Weise können Sie die Kollatierung der Spalten angeben. Oder verwenden Sie stattdessen Tabellenvariablen.

+0

Bitte sehen Sie sich mein Skript an. danke – illumi

+0

@dave, er gab dir die Antwort. In Ihrem Skript kann Ihnen niemand sagen, wo Sie die COLLATE-Anweisung benötigen. Der Kollatierungskonflikt tritt irgendwo auf, wo die Spalte einer Tabelle auf eine andere Kollatierung als eine andere oder eine andere als die Standardeinstellung des Servers oder der Datenbank eingestellt ist. – ErikE

6

Wenn Sie vergleichen/Aggregat-Spalten mit unterschiedlichen Sortierungen Sie zumindest einer von ihnen zu der Vereinigungs Kohärenz müssen Sie wollen, mit dem COLLATE Ausdruck.Zum Beispiel, sagen Sie Table1 und eine Säule c2 mit Sortierungs SQL_Latin1_General_CP1_CI_AS in Tabelle Table2 und Sie möchten Vereinigung der beiden Latin1_General_CI_AI in Tabelle eine Spalte c1 mit Sortierung haben:

SELECT c1 COLLATE SQL_Latin1_General_CP1_CI_AS 
FROM Table1 
UNION ALL 
SELECT c2 
FROM Table2; 
2

Es ist wie diese Frage aussieht, ist eine alte Frage, aber ich Ich werde sowieso eine Antwort geben, weil ich in letzter Zeit ein ähnliches Problem hatte und dachte, es könnte jemand anderem etwas Kummer ersparen!

Überprüfen Sie Ihre Tabellenerstellskripts für die Datenbank, da sie möglicherweise die Kollatierungen in den Spalten zur Erstellungszeit festlegen. Was nicht unbedingt zu einem späteren Zeitpunkt im Entwicklungszyklus führen muss. das heißt, wie die Instanz identifizieren Sie hier, dass Sie versuchen, ein Gleichheitsvergleich vorzuformen

select a.nOrder, a.cInterval, a.cCode, c.cName, (c.cFirstName + ' ' + case when isnull(c.cMiddleInitial,'')='' then '' else c.cMiddleInitial + ' ' end + c.cLastName) as cCustomerName, (case when **isnull(c.cBusinessName,'')=''** then c.cName else c.cBusinessName end) as cBusinessName,   c.cAddress, c.cLastName, c.cJobTitle, d.cCompanyName, d.cAddress1, d.cAddress2, d.cPhone, d.cfax, d.cEmail, c.cTerm, b.cInvNo, b.nBalance, b.dDate, b.nGross, b.cRefNo, b.dRefDate, b.nBeg, b.nEnd, b.nConsumed, b.nCOnsumedKG,   b.nPrice, b.nAmount, b.nVat, b.nWHT, b.nNet, isnull(e.nTotalPDC,0) as nTotalPDC, f.nTotalAR, f.nTotalPastDue, c.nLimit, @dDateFrom as dStartDate, @dDateTo as dEndDate,--g.cTenantName,   b.cTenantName,(CASE WHEN @cFilter = 'Show Note' THEN 1 ELSE 0 END) AS lNot 

ich es fett markiert haben. Mein Problem scheint von der Tatsache herrühren, dass einige unserer Tabellen in SQL Management Studio erstellt wurden und einige Tabellen in Visual Studio erstellt wurden, die unterschiedliche Sortiereinstellungen aktiviert hatten. Es hat lange gedauert, das herauszufinden. Erst nachdem ich die Datenbankskripte gelesen hatte, nahm ich es auf. Wir haben nun mit der Datenbank-Entwickler-Edition in Visual Studio Premium begonnen, die unser Datenbank-Konfigurationsmanagement vereinfacht hat.

Verwandte Themen