Hvis du har stødt på fejlmeddelelsen 7325 i SQL Server "Objekter, der eksponerer kolonner med CLR-typer, er ikke tilladt i distribuerede forespørgsler", er det sandsynligvis fordi du forsøger at køre en distribueret forespørgsel mod en tabel, der indeholder en eller flere kolonner med CLR-typer.
For eksempel kan du forespørge på en tabel, der bruger en geografi eller geometri datatype i en eller flere af dens kolonner. Disse datatyper er implementeret som .NET Common Language Runtime (CLR) datatyper i SQL Server. Og som fejlmeddelelsen siger:"Objekter, der eksponerer kolonner med CLR-typer, er ikke tilladt i distribuerede forespørgsler".
Heldigvis er der en nem løsning på dette problem. Og svaret er forsynet med den fulde fejlmeddelelse.
Henter fejlen
Her er et eksempel på en distribueret forespørgsel, der resulterer i fejl 7325.
SELECT TOP(10) * FROM Homer.WideWorldImportersDW.Dimension.City;
Resultat:
Msg 7325, Level 16, State 1, Line 1 Objects exposing columns with CLR types are not allowed in distributed queries. Please use a pass-through query to access remote object '"WideWorldImportersDW"."Dimension"."City"'.
I dette tilfælde kørte jeg en distribueret forespørgsel mod en forbundet server kaldet "Homer". Jeg prøvede at forespørge på "Dimension.City"-tabellen på "WideWorldImportersDW"-databasen, men det virkede ikke. Tilsyneladende indeholder tabellen en CLR-type.
Fejlmeddelelsen antyder, at jeg i stedet bruger en pass-through-forespørgsel:
Please use a pass-through query to access remote object '"WideWorldImportersDW"."Dimension"."City"'.
Rettelse af fejlen – Pass-Through Query
Jeg er ikke sikker på, om dette faktisk er klassificeret som at "rette" fejlen eller blot som "at omgå" fejlen. Uanset hvad, fortæller fejlmeddelelsen mig, at jeg skal bruge en pass-through-forespørgsel, så det er, hvad jeg vil gøre.
Ved at bruge en pass-through-forespørgsel kan vi køre forespørgsler mod eksterne tabeller, der indeholder kolonner med CLR-typer.
Så vi kunne ændre den tidligere forespørgsel til følgende:
SELECT TOP(10) * FROM OPENQUERY( Homer, 'SELECT * FROM WideWorldImportersDW.Dimension.City' );
Når jeg kører den forespørgsel, får jeg de forventede resultater uden fejl.
OPENQUERY()
funktion giver os mulighed for at køre en pass-through-forespørgsel på den angivne linkede server. Det første argument indeholder det linkede servernavn, og det andet argument er den forespørgsel, som vi ønsker at køre (omgivet af enkelte anførselstegn).
Så du kan kopiere den originale forespørgsel og indsætte den som det andet argument. Hvis du gør dette, så glem ikke at fjerne det linkede servernavn fra forespørgslen, ellers får du endnu en fejl. I mit eksempel var jeg nødt til at fjerne "Homer" fra Homer.WideWorldImportersDW.Dimension.City
, så det blev WideWorldImportersDW.Dimension.City
. Dette skyldes, at vi allerede angiver navnet på den sammenkædede server i det første argument.
Sådan finder du den skyldige
Som nævnt fortalte fejlmeddelelsen mig, at jeg forsøgte at forespørge på en kolonne med en CLR-type. Jeg kan bekræfte dette ved at hoppe over til den eksterne (linkede) server og køre følgende kode:
USE WideWorldImportersDW; SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'City' AND TABLE_SCHEMA = 'Dimension';
Resultat:
+----------------------------+-------------+ | COLUMN_NAME | DATA_TYPE | |----------------------------+-------------| | City Key | int | | WWI City ID | int | | City | nvarchar | | State Province | nvarchar | | Country | nvarchar | | Continent | nvarchar | | Sales Territory | nvarchar | | Region | nvarchar | | Subregion | nvarchar | | Location | geography | | Latest Recorded Population | bigint | | Valid From | datetime2 | | Valid To | datetime2 | | Lineage Key | int | +----------------------------+-------------+
Vi kan se, at Placeringen kolonne har datatypen geografi , som er en CLR-type. Dette er den mest sandsynlige årsag til fejlen.