【问题标题】:Create View in specified MSSQL-Schema在指定的 MSSQL-Schema 中创建视图
【发布时间】:2014-10-06 22:15:55
【问题描述】:

我使用的是 Apache Tomcat 7.0.41,需要使用官方“com.microsoft.sqlserver.jdbc.SQLServerDriver”驱动程序在 SQL Server 2012 上生成视图。 不幸的是,选择架构似乎有问题。我尝试了几种方法来完成它,但每次都失败了。

奇怪的是,定期创建表不会造成任何麻烦:

CREATE TABLE Defschem.dbo.Formate (
[FormatID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[Info] [varchar](50) NOT NULL UNIQUE,
[FVal] [float] NOT NULL)

尝试以相同的方式进行查看。 (仅供参考:语句本身和表名都是分开的final Strings,可以单独更改) :

Create View Defschem.dbo.EtiFormatview as 
SELECT 
...
 FROM Defschem.dbo.Formate  
...

因错误而失败:

com.microsoft.sqlserver.jdbc.SQLServerException: 'CREATE/ALTER VIEW' 不允许将数据库名称指定为对象的前缀 名字。
在 com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216)

完全保留数据库名称会将创建的视图放入“主”数据库中,这并不是我想要的。

错误很常见,http://www.sql-server-helper.com/error-messages/msg-166.aspx 建议:

为避免此错误,请在创建视图时删除数据库名称: [...] 如果您需要在另一个数据库上创建视图,请更改您的 先创建数据库,然后创建没有数据库名称的视图:

USE Northwind
GO

CREATE VIEW [dbo].[CustomerCountries]
AS
SELECT DISTINCT [Country]
FROM [dbo].[Customers]
GO

我已经启动了整个 SQL 命令:

"USE " + DATABASENAME + '\n' + "GO " + '\n';

到:

USE Defschem
GO 
Create View Defschem.dbo.EtiFormatview as 
    SELECT 
    ...
     FROM Defschem.dbo.Formate  
    ...

得到错误:

com.microsoft.sqlserver.jdbc.SQLServerException:附近的语法不正确 '去'。

我不确定我的 '\n 是否对于 SQL-Server 来说不够漂亮...我不明白为什么语法应该不正确,所以我将整个 SQL 插入到 SQL -Management Studio...并且成功了!

我很难理解为什么同一个命令可以在 Studio 中工作,但如果用 Java 执行则不能? 该命令很简单(我使用常规语句而不是准备语句,因为我不插入任何值并且我的所有字符串都是最终的):

stat = c.createStatement();
stat.executeUpdate(Info.getUsage()+VIEW);
c.commit();

官方文档(http://msdn.microsoft.com/en-us/library/ms187956.aspx - 请参阅“示例”部分)指的是在 GO SCHEMA 之后使用分号的情况。 但是改为:

"USE " + DATABASENAME + ";\n" + "GO " + '\n';

给了我完全相同的错误。离开 '\n's 也没有效果。

似乎有人不久前遇到了类似的问题: How can I specify the current schema for sql server in a jboss data source url?

我以前没有使用过同义词,我认为这不是解决我的问题的正确方法。有没有更优雅的解决方案?

谢谢

【问题讨论】:

    标签: java sql-server jdbc view database-schema


    【解决方案1】:

    USE 这样的语句在技术上可以在 JDBC 中使用。但是,您不能使用GO,因为这不是 SQL Server T-SQL 语法的一部分;它实际上是 SQL Server Management Studio 的一部分,也是 SQL Server 的一些脚本工具。

    但是 JDBC 强烈建议不要直接使用影响连接状态的命令(包括其他命令,例如事务(启动、提交回滚)):

    注意:配置Connection时,JDBC应用程序应使用适当的连接方法,例如setAutoCommitsetTransactionIsolation。当有可用的 JDBC 方法时,应用程序不应直接调用 SQL 命令来更改连接的配置。 (来自java.sql.Connection

    如果要切换数据库,可以使用Connection.setCatalog()。这样,连接就知道它现在连接到不同的目录。如果您改为使用USE 执行此操作,驱动程序可能仍然认为它已连接到初始数据库并执行错误的操作(例如为错误的数据库缓存元数据等)。

    当然,the answer by Donal 中描述了另一个选项:直接连接到正确的数据库。

    【讨论】:

    • 你说得对——我以前从未处理过USEGO 命令(并且很高兴不再使用它)。然而,@Donai 的回答对我不起作用,但使用目录设置它应该继续进行。
    【解决方案2】:

    您可以将数据库名称指定为连接字符串的一部分。这意味着您不需要USE 语句 - 因为连接字符串中的数据库是您当前的数据库。

    例如:

    String connectionUrl = "jdbc:sqlserver://servername:1433;databaseName=TheActualDatabaseName;user=UserName;password=*****;";
    Connection con = DriverManager.getConnection(connectionUrl);
    

    一旦连接到数据库,您就不需要在 SQL 中使用它。您也不需要使用架构名称 - dbo 是 SQL Server 中的默认架构,您可以将其省略。

    例如:

    CREATE TABLE Formate (
    [FormatID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [Info] [varchar](50) NOT NULL UNIQUE,
    [FVal] [float] NOT NULL)
    )
    

    【讨论】:

    • SQL-Server 似乎导致了 Schema/DB-Options 的问题,它没有工作......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-16
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 1970-01-01
    • 1970-01-01
    • 2016-12-04
    相关资源
    最近更新 更多