Передача представлений - для 'value ()' требуется одиночный (или пустая последовательность) найденный операнд типа 'xdt: untypedAtomic *' - PullRequest
1 голос
/ 02 октября 2019

Я пытаюсь перенести представления из базы данных AdventureWorks2014 с одного SQL Server на другой, используя Java и JDBC.

Чтобы получить структуру представления, я использую хранимую процедуру "sp_helptext" следующим образом:

ResultSet rs = statement.executeQuery("EXEC sp_helptext \'" + view + "\';");

где представление - это схема и имя представления(например, «dbo.myview»), который я сейчас передаю.

При выполнении команды для представления «Person.vAdditionalContactInfo» возвращается следующая структура:

CREATE VIEW [Person].[vAdditionalContactInfo]   
AS   
SELECT   
    [BusinessEntityID]   
    ,[FirstName]  
    ,[MiddleName]  
    ,[LastName]  
    ,[ContactInfo].ref.value(N'declare namespace ci="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";   
        declare namespace act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";   
        (act:telephoneNumber)[1]/act:number', 'nvarchar(50)') AS [TelephoneNumber]   
    ,LTRIM(RTRIM([ContactInfo].ref.value(N'declare namespace ci="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";   
        declare namespace act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";   
        (act:telephoneNumber/act:SpecialInstructions/text())[1]', 'nvarchar(max)'))) AS [TelephoneSpecialInstructions]   
    ,[ContactInfo].ref.value(N'declare namespace ci="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";   
        declare namespace act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";  
        (act:homePostalAddress/act:Street)[1]', 'nvarchar(50)') AS [Street]   
    ,[ContactInfo].ref.value(N'declare namespace ci="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";   
        declare namespace act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";   
        (act:homePostalAddress/act:City)[1]', 'nvarchar(50)') AS [City]   
    ,[ContactInfo].ref.value(N'declare namespace ci="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";   
        declare namespace act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";   
        (act:homePostalAddress/act:StateProvince)[1]', 'nvarchar(50)') AS [StateProvince]   
    ,[ContactInfo].ref.value(N'declare namespace ci="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";   
        declare namespace act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";   
        (act:homePostalAddress/act:PostalCode)[1]', 'nvarchar(50)') AS [PostalCode]   
    ,[ContactInfo].ref.value(N'declare namespace ci="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";   
        declare namespace act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";   
        (act:homePostalAddress/act:CountryRegion)[1]', 'nvarchar(50)') AS [CountryRegion]   
    ,[ContactInfo].ref.value(N'declare namespace ci="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";   
        declare namespace act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";   
        (act:homePostalAddress/act:SpecialInstructions/text())[1]', 'nvarchar(max)') AS [HomeAddressSpecialInstructions]   
    ,[ContactInfo].ref.value(N'declare namespace ci="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";   
        declare namespace act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";   
        (act:eMail/act:eMailAddress)[1]', 'nvarchar(128)') AS [EMailAddress]   
    ,LTRIM(RTRIM([ContactInfo].ref.value(N'declare namespace ci="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";   
        declare namespace act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";   
        (act:eMail/act:SpecialInstructions/text())[1]', 'nvarchar(max)'))) AS [EMailSpecialInstructions]   
    ,[ContactInfo].ref.value(N'declare namespace ci="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";   
        declare namespace act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";   
        (act:eMail/act:SpecialInstructions/act:telephoneNumber/act:number)[1]', 'nvarchar(50)') AS [EMailTelephoneNumber]   
    ,[rowguid]   
    ,[ModifiedDate]  
FROM [Person].[Person]  
OUTER APPLY [AdditionalContactInfo].nodes(  
    'declare namespace ci="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";   
    /ci:AdditionalContactInfo') AS ContactInfo(ref)   
WHERE [AdditionalContactInfo] IS NOT NULL;

Следующим шагом является выполнение извлеченного оператора в целевой базе данных:

try(Statement statement = connection.createStatement()) {
    // Retrieve the statement by concatenating every row of the result set
    StringBuilder sb = new StringBuilder();
    while(resultSet.next()) {
        sb.append(resultSet.getString(1));
    }
    // Execute the update statement 
    return statement.executeUpdate(sb.toString()) > 0;
} catch(SQLException e) {
    Logger.getLogger().severe("Exception occurred while transferring view!");
    Logger.getLogger().log(Level.SEVERE, e.getMessage(), e);
}

Для каждого представления в базе данных AdventureWorks2014 это работало просто отлично. Но для представления «Person.vAdditionalContactInfo» после выполнения оператора обновления на целевом SQL Server возвращается следующая ошибка:

SEVERE: XQuery [Person.Person.AdditionalContactInfo.value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *'
com.microsoft.sqlserver.jdbc.SQLServerException: XQuery [Person.Person.AdditionalContactInfo.value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *'
        at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:256)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1621)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.doExecuteStatement(SQLServerStatement.java:868)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement$StmtExecCmd.doExecute(SQLServerStatement.java:768)
        at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7194)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:2930)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:248)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:223)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeUpdate(SQLServerStatement.java:711)
        at main.synchronizer.Synchronizer.transferView(Synchronizer.java:893)
        at main.synchronizer.Synchronizer.transferViews(Synchronizer.java:858)
        at main.synchronizer.Synchronizer.executeDirectMode(Synchronizer.java:135)
        at main.synchronizer.Synchronizer.run(Synchronizer.java:69)

Я искал решения в Интернете, но не нашелодин. Любая помощь будет принята с благодарностью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...