Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
执行;sp_msforeachdb";在Java应用程序中_Java_Sql Server_Stored Procedures_Jdbc_Sp Msforeachdb - Fatal编程技术网

执行;sp_msforeachdb";在Java应用程序中

执行;sp_msforeachdb";在Java应用程序中,java,sql-server,stored-procedures,jdbc,sp-msforeachdb,Java,Sql Server,Stored Procedures,Jdbc,Sp Msforeachdb,嗨,社区:) 我来和你分享我的一个问题 我必须提取SQL Server实例的每个数据库中每个表的列表,我发现以下查询: EXEC sp_msforeachdb 'Use ?; SELECT DB_NAME() AS DB, * FROM sys.tables' 它在MicrosoftSQLServerManagementStudio上运行得非常好,但是当我尝试在Java程序中执行它时(包括用于SQLServer的JDBC驱动程序),它说它不会返回任何结果 我的Java代码如下所示: this.

嗨,社区:)

我来和你分享我的一个问题

我必须提取SQL Server实例的每个数据库中每个表的列表,我发现以下查询:

EXEC sp_msforeachdb 'Use ?; SELECT DB_NAME() AS DB, * FROM sys.tables'
它在MicrosoftSQLServerManagementStudio上运行得非常好,但是当我尝试在Java程序中执行它时(包括用于SQLServer的JDBC驱动程序),它说它不会返回任何结果

我的Java代码如下所示:

this.statement = this.connect.createStatement(); // Create the statement
this.resultats = this.statement.executeQuery("EXEC sp_msforeachdb 'Use ?; SELECT DB_NAME() AS DB, * FROM sys.tables'"); // Execute the query and store results in a ResultSet

this.sortie.ecrireResultats(this.statement.getResultSet()); // Write the ResultSet to a file
+-----------+--------+
| Databases | Tables |
+-----------+--------+
this.instances = instances;
for(int i = 0 ; i < this.instances.size() ; i++)
{
    try
    {
        Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        this.connect = DriverManager.getConnection("jdbc:sqlserver://" + this.instances.get(i), "tluser", "result");

        this.statement = this.connect.prepareCall("{call sp_msforeachdb(?)}");
        this.statement.setString(1, "Use ?; SELECT DB_NAME() AS DB, name FROM sys.tables WHERE DB_NAME() NOT IN('master', 'model', 'msdb', 'tempdb')");
        this.resultats = this.statement.execute();

        while(true)
        {
            int rowCount = this.statement.getUpdateCount();
            if(rowCount > 0)
            {
                this.statement.getMoreResults();
                continue;
            }
            if(rowCount == 0)
            {
                this.statement.getMoreResults();
                continue;
            }

            ResultSet rs = this.statement.getResultSet();
            if(rs != null)
            {
                while (rs.next())
                {
                     this.sortie.ecrireResultats(rs); // Write the results to a file
                }
                rs.close();
                this.statement.getMoreResults();
                continue;
            }
            break;
        }
        this.statement.close();
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}
感谢所有愿意帮助我的人, 祝你今天愉快:)

编辑1:

我不确定SQL Server的JDBC驱动程序是否支持我的查询,因此我将尝试以另一种方式实现我的目标

我试图得到的是SQL Server实例上每个数据库的所有表的列表,输出格式如下:

this.statement = this.connect.createStatement(); // Create the statement
this.resultats = this.statement.executeQuery("EXEC sp_msforeachdb 'Use ?; SELECT DB_NAME() AS DB, * FROM sys.tables'"); // Execute the query and store results in a ResultSet

this.sortie.ecrireResultats(this.statement.getResultSet()); // Write the ResultSet to a file
+-----------+--------+
| Databases | Tables |
+-----------+--------+
this.instances = instances;
for(int i = 0 ; i < this.instances.size() ; i++)
{
    try
    {
        Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        this.connect = DriverManager.getConnection("jdbc:sqlserver://" + this.instances.get(i), "tluser", "result");

        this.statement = this.connect.prepareCall("{call sp_msforeachdb(?)}");
        this.statement.setString(1, "Use ?; SELECT DB_NAME() AS DB, name FROM sys.tables WHERE DB_NAME() NOT IN('master', 'model', 'msdb', 'tempdb')");
        this.resultats = this.statement.execute();

        while(true)
        {
            int rowCount = this.statement.getUpdateCount();
            if(rowCount > 0)
            {
                this.statement.getMoreResults();
                continue;
            }
            if(rowCount == 0)
            {
                this.statement.getMoreResults();
                continue;
            }

            ResultSet rs = this.statement.getResultSet();
            if(rs != null)
            {
                while (rs.next())
                {
                     this.sortie.ecrireResultats(rs); // Write the results to a file
                }
                rs.close();
                this.statement.getMoreResults();
                continue;
            }
            break;
        }
        this.statement.close();
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}
所以现在我想问有人能帮我通过Java的JDBC for SQL Server驱动程序使用SQL查询找到解决方案吗


我还想感谢从和得到的非常快速的答案。

如果您没有收到错误,一个问题可能是
sp_msforeachdb
将为每个数据库返回一个单独的结果集,而不是一个包含所有记录的结果集。在这种情况下,您可以尝试使用一点动态SQL来合并所有行:

-- Use sys.tables
declare @sql nvarchar(max)
select @sql = coalesce(@sql + ' union all ', '') + 'select ''' + quotename(name) + ''' as database_name, * from ' + quotename(name) + '.sys.tables'
from sys.databases
select @sql = @sql + ' order by database_name, name'
exec sp_executesql @sql
我有时也会使用信息模式视图,因为更容易看到模式名称以及其他内容:

-- Use INFORMATION_SCHEMA.TABLES to easily get schema name
declare @sql nvarchar(max)
select @sql = coalesce(@sql + ' union all ', '') + 'select * from ' + quotename(name) + '.INFORMATION_SCHEMA.TABLES where TABLE_TYPE = ''BASE TABLE'''
from sys.databases
select @sql = @sql + ' order by TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME'
exec sp_executesql @sql

请注意,这种字符串连接方法(
select@sql=foo from bar
)(它只会获取最后一条记录)。只是一个小小的警告。

如果一个语句可以返回no或多个结果,则不应使用
executeQuery
,而是该方法返回一个
布尔值,指示第一个结果的类型:

  • true
    :结果是一个
    ResultSet
  • false
    :结果是更新计数
如果结果为
true
,则使用检索
ResultSet
,否则检索更新计数。如果更新计数为
-1
,则表示没有更多结果。请注意,当当前结果为
ResultSet
时,更新计数也将为
-1
。如果没有更多的结果或者结果是更新计数,
getResultSet()
应该返回null,这也是一个好消息

现在,如果您想检索更多结果,可以调用(或其兄弟接受
int
参数)。
boolean
的返回值与
execute()
的返回值具有相同的含义,因此
false
并不意味着没有更多的结果

只有当
getMoreResults()
返回false并且
getUpdateCount()
返回
-1
时,才会有更多的结果(正如Javadoc中所述)

本质上,这意味着如果您想正确处理所有结果,您需要执行以下操作:

boolean result = stmt.execute(...);
while(true)
    if (result) {
        ResultSet rs = stmt.getResultSet();
        // Do something with resultset ...
    } else {
        int updateCount = stmt.getUpdateCount();
        if (updateCount == -1) {
            // no more results
            break;
        }
        // Do something with update count ...
    }
    result = stmt.getMoreResults();
}

注:部分答案基于我对更新的回答

我找到了解决办法

读过之后,我发现我也遇到了同样的情况

我的最终代码如下:

this.statement = this.connect.createStatement(); // Create the statement
this.resultats = this.statement.executeQuery("EXEC sp_msforeachdb 'Use ?; SELECT DB_NAME() AS DB, * FROM sys.tables'"); // Execute the query and store results in a ResultSet

this.sortie.ecrireResultats(this.statement.getResultSet()); // Write the ResultSet to a file
+-----------+--------+
| Databases | Tables |
+-----------+--------+
this.instances = instances;
for(int i = 0 ; i < this.instances.size() ; i++)
{
    try
    {
        Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        this.connect = DriverManager.getConnection("jdbc:sqlserver://" + this.instances.get(i), "tluser", "result");

        this.statement = this.connect.prepareCall("{call sp_msforeachdb(?)}");
        this.statement.setString(1, "Use ?; SELECT DB_NAME() AS DB, name FROM sys.tables WHERE DB_NAME() NOT IN('master', 'model', 'msdb', 'tempdb')");
        this.resultats = this.statement.execute();

        while(true)
        {
            int rowCount = this.statement.getUpdateCount();
            if(rowCount > 0)
            {
                this.statement.getMoreResults();
                continue;
            }
            if(rowCount == 0)
            {
                this.statement.getMoreResults();
                continue;
            }

            ResultSet rs = this.statement.getResultSet();
            if(rs != null)
            {
                while (rs.next())
                {
                     this.sortie.ecrireResultats(rs); // Write the results to a file
                }
                rs.close();
                this.statement.getMoreResults();
                continue;
            }
            break;
        }
        this.statement.close();
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}
this.instances=实例;
对于(int i=0;i0)
{
this.statement.getMoreResults();
继续;
}
如果(行计数==0)
{
this.statement.getMoreResults();
继续;
}
ResultSet rs=this.statement.getResultSet();
如果(rs!=null)
{
while(rs.next())
{
this.sortie.ecriresults(rs);//将结果写入文件
}
rs.close();
this.statement.getMoreResults();
继续;
}
打破
}
这个.statement.close();
}
捕获(例外e)
{
e、 printStackTrace();
}
}
它试过了,我的文件里有我想要的一切


谢谢大家的帮助!:)

哇,快速回答!我可以把它包含到我的Java程序中吗?我对JDBC不太熟悉,所以我只是猜测你可以把这整个东西放在
executeQuery()
命令中。如果这不起作用,您可以尝试使用基本的
exec sp_who
或其他方法,以确保可以通过这种方式从进程中获得结果集。使用与你的应用程序相同的用户/密码登录SSMS也不会有什么坏处。我明天会尝试,并会通知你我的进展情况。无论如何,谢谢你的帮助!你的帖子很完整,教了我很多关于一些方法还没有掌握。问题是我实现了你的解决方案,但我无法让它与我的查询一起工作。。。“我认为司机不支持。”VincentKelleher不幸的是,我会看看是否能找到替代方案。非常感谢!我花了好几天的时间到处搜索,似乎没有人尝试过。。。