Ich arbeite an einem Skript, um eine Umgebung von einem Server auf einen anderen zu portieren. Beim Aufrufen eines Problems wird catalog.create_environment_variable
die Fehlermeldung "Der Datentyp des Eingabewerts ist nicht mit dem Datentyp der Zeichenfolge kompatibel" angezeigt. kommt aus dem proc "check_data_type_value".
Merkwürdig ist, dass diese Abfrage funktionieren würde, wenn ich das GUI-Skript die Variablen auslassen würde
DECLARE @var sql_variant = N'\\myserver\ssisdata'
EXEC [catalog].[create_environment_variable]
@variable_name = N'FolderBase'
, @sensitive = False
, @description = N''
, @environment_name = N'Development'
, @folder_name = N'POC'
, @value = @var
, @data_type = N'String'
GO
Dieser Skriptansatz funktioniert jedoch nicht. Die von mir durchgeführten Vorarbeiten weisen darauf hin, dass diese Fehlermeldung normalerweise mithilfe des Datentyps nvarchar anstelle von varchar behoben wird. Für meine Sachen ist das jedoch nicht der Fall.
Zeile 108 für das folgende Skript. Ich gehe davon aus, dass es etwas Wackeliges mit der sql_variant ist, aber ich habe keine Ahnung, was das für ein Ding ist.
USE SSISDB;
GO
DECLARE
@folder_id bigint
, @folder_name nvarchar(128) = N'POC'
, @environment_name nvarchar(128) = N'Development'
, @environment_description nvarchar(1024)
, @reference_id bigint
, @variable_name nvarchar(128)
, @data_type nvarchar(128)
, @sensitive bit
, @value sql_variant
, @description nvarchar(1024);
IF NOT EXISTS
(
SELECT * FROM catalog.folders AS F WHERE F.name = @folder_name
)
BEGIN
EXECUTE catalog.create_folder
@folder_name = @folder_name
, @folder_id = @folder_id OUTPUT;
PRINT CONCAT('Folder "', @folder_name, '" has been created with a folder_id of ', @folder_id)
END
IF NOT EXISTS
(
SELECT * FROM catalog.environments AS E WHERE E.name = @environment_name
AND E.folder_id = (SELECT F.folder_id FROM catalog.folders AS F WHERE F.name = @folder_name)
)
BEGIN
PRINT CONCAT('Creating environment ', @environment_name);
EXECUTE catalog.create_environment
@folder_name = @folder_name
, @environment_name = @environment_name
, @environment_description = @environment_description;
END
DECLARE
@EnvironmentVariables TABLE
(
folder_name nvarchar(128)
, environment_name nvarchar(128)
, variable_name nvarchar(128)
, description nvarchar(1024)
, data_type nvarchar(128)
, sensitive bit
, value sql_variant
);
INSERT INTO
@EnvironmentVariables
SELECT
E.folder_name
, E.environment_name
, S.name
, S.description
, S.type
, S.sensitive
, S.value
FROM
(
SELECT 'FolderBase','Root for ssis processing','String',CAST(0 AS bit),'\\myserver\ssisdata'
UNION ALL SELECT 'AuditConnectionString','Conn to audit db','String',CAST(0 AS bit),'Data Source=SQLETL01;Initial Catalog=Audit;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;'
) AS S (name, description, type, sensitive, value)
CROSS APPLY
(
SELECT
E.name AS environment_name
, F.name AS folder_name
FROM
catalog.folders AS F
INNER JOIN
catalog.environments AS E
ON E.folder_id = F.folder_id
WHERE
F.name = @folder_name
AND E.name = @environment_name
) E;
DECLARE Csr CURSOR FORWARD_ONLY STATIC FOR
SELECT
EV.variable_name
, EV.description
, EV.data_type
, EV.sensitive
, EV.value
FROM
@Environmentvariables AS EV;
OPEN Csr;
FETCH NEXT FROM Csr INTO
@variable_name
, @description
, @data_type
, @sensitive
, @value;
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN TRY
-- THERE BE MONSTERS AHEAD
-- The data type of the input value is not compatible with the data type of the 'String'.
EXECUTE catalog.create_environment_variable
@variable_name = @variable_name
, @sensitive = @sensitive
, @description = @description
, @environment_name = @environment_name
, @folder_name = @folder_name
, @value = @value
, @data_type = @data_type
END TRY
BEGIN CATCH
SELECT
@folder_name AS folder_name
, @environment_name AS environment_name
, @variable_name AS variable_name
, @data_type AS data_type
, @sensitive AS sensitive
, @value AS value
, @description AS description
, ERROR_NUMBER()AS error_number --returns the number of the error.
, ERROR_SEVERITY() AS error_severity --returns the severity.
, ERROR_STATE()AS error_state --returns the error state number.
, ERROR_PROCEDURE() AS error_procedure --returns the name of the stored procedure or trigger where the error occurred.
, ERROR_LINE() AS error_line --returns the line number inside the routine that caused the error.
, ERROR_MESSAGE() AS error_message; --returns the complete text of the error message. The text includes the values supplied for any substitutable parameters, such as lengths, object names, or times.
END CATCH
FETCH NEXT FROM Csr INTO
@variable_name
, @description
, @data_type
, @sensitive
, @value;
END
CLOSE Csr;
DEALLOCATE Csr;
quelle
Antworten:
"Die Arbeit, die ich gemacht habe, zeigt an, dass diese Fehlermeldung normalerweise mit dem Datentyp nvarchar anstelle von varchar behoben wird. Dies ist jedoch für meine Daten nicht der Fall." Oder ist es so?
Ich habe zwei Änderungen an meinem Cursor vorgenommen. Der erste befindet sich in meinem CATCH-Block. Ich las den Artikel über den Datentyp sql_variant noch einmal und folgte mit der Eigenschaft sql_variant_property . Ich habe einen Anruf , dass in meinem catch - Block, um zu sehen , erwartete
nvarchar
aber lo und siehe, es meldet zurück ,varchar
wie mein Basetype.Da ich weiß, dass alle meine Quelldaten
@local
zeichenbasiert sind , habe ich die Variable betrogen und mit einer expliziten Umwandlung in nvarchar hinzugefügt, und sie funktioniert auf magische Weise.Ursachenanalyse
Als ich anfing, eine Zusammenfassung der Ergebnisse zu schreiben, entdeckte ich die Trennung. Als ich meine temporäre Tabelle, @EnvironmentVariables, lud, hatte ich diese ursprünglich direkt von übernommen.
catalog.environment_variables.
Um sie portabler zu machen, kopierte ich die Werte als SELECT-Anweisungen heraus. Dies ist, wo ich vermasselt habe. Bei der Wiederherstellung dieser Werte habe ich die Unicode-Zeichenfolgen in Mercan-Zeichenfolgen umgewandelt. Sie wurden als Nicht-Unicode in die Spalte vom Typ sql_variant geschrieben, die dann explodierte, als sie zur Validierung im proc übergeben wurden. Wenn ich meine Zeichenfolgen korrekt mit demN
Modifikator (?) Vorstelle, werden sie als nvarchar gespeichert.quelle
N
aber ich habe immer noch dieses Problem. Tatsächlich erhalte ich Beschwerden über Boolean und Datetime, aber keiner meiner Parameter verwendet diesen Datentyp. Hast du irgendwelche Einsichten?Nur um @billinkc eine ausgezeichnete Antwort hinzuzufügen (Sie wussten doch, dass Sie die Antwort auf diese Frage sein würden !!) und das Wissen um diese Frage zu bereichern ...
Hier ist ein Beispielcode, der von hier aus automatisch generiert wurde https://thefirstsql.com/2013/05/28/ssis-2012-easily-copy-environment-variables-to-new-servers-or-new-environments/ , der den Fehler auslöst :
Insbesondere ist der Fehler
Ich hatte auch andere Fehler für datetime und boolean
Daher bestand die Lösung, ohne das Problem zu verstehen, darin, einen bestimmten Datentyp zu verwenden, anstatt
sql_variant
einen Wert an den@value
Parameter zu übergeben.Für Int64 und Boolean können Sie nur den Wert harter Code , sondern für
datetime
Sie müssen vorab eine Variable vom Typ deklarierendatetime
und verwenden Sie es - Sie können nicht nur in einem String Datumsliteral passierenDies ist das erste Mal, dass ich einen Parameter in einer gespeicherten Prozedur sehe, der anscheinend eine Vielzahl von Datentypen akzeptiert.
quelle