java - 转移视图 - 'value()' 需要一个单例(或空序列),找到类型为 'xdt:untypedAtomic *' 的操作数
问题描述
我正在尝试使用 Java 和 JDBC 将 AdventureWorks2014 数据库中的视图从一个 SQL Server 传输到另一个。
为了获得视图的结构,我像这样使用存储过程“sp_helptext”:
ResultSet rs = statement.executeQuery("EXEC sp_helptext \'" + view + "\';");
其中 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)
我在互联网上四处寻找解决方案,但还没有找到。任何帮助将不胜感激。
解决方案
尝试创建上述视图时发生的错误是由视图引用的表列引起的。
在迁移 AdventureWorks2014 数据库的所有视图之前,我使用自定义 T-SQL 脚本生成表创建语句,以类似于视图迁移表。脚本中的一个错误导致 XML 列被创建为与 XML 列不同的东西,这解释了为什么对预期是 XML 列的一个这样的列(AdditionalContactInfo
表 )的访问会导致此错误。Person.Person
推荐阅读
- r - 如何使用 for 循环获取每个列的异常值?
- java - 通过 Java 中的接口调用时变量赋值被延迟
- c# - 将 StringSegment 附加到 StringBuilder
- python - 如何将 pandas 数据框转换为具有列名的 numpy 数组
- django - 以条带形式访问 webbook 中的优惠券信息
- json - 通过 Cloud Formation 控制数据库安全组端口访问
- json - Rocket 无法解析 JSON 正文
- python - Pytss:将参数传递给 fapi_Sign() 方法 - 无效的参数类型(类型为 uint8_t const * 的 Fapi_Sign 参数 4)
- c++ - 在两个字符串 C++ 中找到最长的子字符串
- java - 尝试在Java中将变量从方法调用到main