我正在使用C#构建分层树形图,我使用sql查询来获取结果。但是,我似乎无法让这一个查询工作。它给了我在sql-server中我需要的东西,但它在C#中不起作用。此查询是否有可能的解决方法? HTML
<div class="Demo">
<h1>Tree Demo</h1>
<div class="tree well">
<ul>
<li><span>ServerName</span>
<ul>
<asp:Repeater ID="rpDatabasesParent" runat="server" OnItemDataBound="loadTables">
<ItemTemplate>
<li><span><%# Eval("Name") %></span>
<ul>
<h3>Tables</h3>
<asp:Repeater ID="rpTablesChild" runat="server" OnItemDataBound="loadTables">
<ItemTemplate>
<li><span><%# Eval("Tables") %></span></li>
</ItemTemplate>
</asp:Repeater>
</ul>
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
</li>
</ul>
</div>
</div>
有问题的查询是我的代码中的第二个查询。它是动态的,它给了我我需要的东西,但我无法让它工作。我需要一个解决方法,如果有的话,可以使这个查询正常工作
C#
protected void Page_Load(object sender, EventArgs e)
{
testConnection();
}
public void testConnection()
{
using (SqlConnection connection = new SqlConnection(masterConnectionString))
{
try
{
connection.Open();
SqlCommand cmd = new SqlCommand("SELECT Name From Sys.Databases", connection);
cmd.CommandType = CommandType.Text;
SqlDataReader rdr = cmd.ExecuteReader();
rpDatabasesParent.DataSource = rdr;
rpDatabasesParent.DataBind();
}
catch (Exception err)
{
//log something
}
finally
{
connection.Close();
}
}
}
protected void loadTables(object sender, RepeaterItemEventArgs e)
{
RepeaterItem item = e.Item;
Repeater rpTablesChild = (Repeater)item.FindControl("rpTablesChild");
using (SqlConnection connection = new SqlConnection(masterConnectionString))
{
try
{
connection.Open();
SqlCommand cmd = new SqlCommand("DECLARE @SERVERNAME SYSNAME = @@SERVERNAME, @DB SYSNAME, @Object SYSNAME, @Str NVARCHAR(4000); DECLARE DBList CURSOR LOCAL FAST_FORWARD FOR SELECT name FROM sys.databases; OPEN DBList; FETCH NEXT FROM DBList INTO @DB; WHILE @@FETCH_STATUS = 0 BEGIN SELECT @Str = 'SELECT name AS Tables FROM '+@DB+'.sys.tables; SELECT TABLE_NAME AS Views FROM '+@DB+'.INFORMATION_SCHEMA.VIEWS; SELECT ROUTINE_NAME AS StoredProcedures FROM '+@DB+'.INFORMATION_SCHEMA.ROUTINES;' EXEC sp_executesql @Str FETCH NEXT FROM DBList INTO @DB; END CLOSE DBList; DEALLOCATE DBList;", connection);
cmd.CommandType = CommandType.Text;
SqlDataReader rdr = cmd.ExecuteReader();
rpTablesChild.DataSource = rdr;
rpTablesChild.DataBind();
}
catch (Exception err)
{
//log something
}
finally
{
connection.Close();
}
}
}
答案 0 :(得分:0)
除此之外,我鼓励您考虑将这段代码转换为存储过程,看起来在很少的地方缺少空格字符。
f.ex:
@StrFETCH
应该是
@Str FETCH
所以整个固定字符串将是:
DECLARE @SERVERNAME SYSNAME= @@SERVERNAME, @DB SYSNAME, @Object SYSNAME, @Str NVARCHAR(4000); DECLARE DBList CURSOR LOCAL FAST_FORWARD FOR SELECT name FROM sys.databases; OPEN DBList; FETCH NEXT FROM DBList INTO @DB; WHILE @@FETCH_STATUS = 0 BEGIN SELECT @Str = 'SELECT name AS Tables FROM '+@DB+'.sys.tables; SELECT TABLE_NAME AS Views FROM '+@DB+'.INFORMATION_SCHEMA.VIEWS; SELECT ROUTINE_NAME AS StoredProcedures FROM '+@DB+'.INFORMATION_SCHEMA.ROUTINES;' EXEC sp_executesql @Str FETCH NEXT FROM DBList INTO @DB; END CLOSE DBList; DEALLOCATE DBList;
此外,您需要考虑此查询将返回多个结果集,因此我不确定使用DataRead是否可以帮助您获得结果。
您可以将所有行合并为1个结果:
CREATE PROCEDURE dbo.GetDbsObjects AS
BEGIN
CREATE TABLE #output (
[Db] SYSNAME,
[Type] VARCHAR(20),
[Name] SYSNAME
)
DECLARE @SERVERNAME SYSNAME= @@SERVERNAME, @DB SYSNAME, @Object SYSNAME, @Str NVARCHAR(4000);
DECLARE DBList CURSOR LOCAL FAST_FORWARD
FOR SELECT name
FROM sys.databases;
OPEN DBList;
FETCH NEXT FROM DBList INTO @DB;
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @Str = 'INSERT INTO #output([Db], [Type], [Name]) SELECT '''+@DB+''', ''table'', name FROM '+@DB+'.sys.tables;'
EXEC sp_executesql @Str
SELECT @Str = 'INSERT INTO #output([Db], [Type], [Name]) SELECT '''+@DB+''', ''view'', TABLE_NAME FROM '+@DB+'.INFORMATION_SCHEMA.VIEWS;'
EXEC sp_executesql @Str
SELECT @Str = 'INSERT INTO #output([Db], [Type], [Name]) SELECT '''+@DB+''', ''stored procedure'', ROUTINE_NAME FROM '+@DB+'.INFORMATION_SCHEMA.ROUTINES;'
EXEC sp_executesql @Str
FETCH NEXT FROM DBList INTO @DB;
END
CLOSE DBList;
DEALLOCATE DBList;
SELECT * FROM #output
DROP TABLE #output
END
然后你应该能够从c#
运行它 ...
connection.Open();
SqlCommand cmd = new SqlCommand("dbo.GetDbsObjects", connection);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataReader rdr = cmd.ExecuteReader();
rpTablesChild.DataSource = rdr;
...
答案 1 :(得分:0)
首先,我相信您的查询中存在一些错误,您的BEGINSELECT应该是BEGIN SELECT,并且在WHILE的BEGIN之后不会以END结束。
如果这不能解决您的问题,也许您可以尝试这种解决方法:
使用输入参数在SQL Server管理中创建存储过程。 然后,您可以使用参数在C#代码中执行该过程。
以下是一个例子:
public DataSet RelaEspec(DateTime dtInicio, DateTime dtFim, string CodNo)
{
string sql = string.Empty;
try
{
sql = "exec store_procedure @dtInicio, @dtFim, @CodNo ";
SqlParameterCollection pCol = new SqlParameterCollection();
pCol.Add("@dtInicio", SqlDbType.DateTime, dtInicio);
pCol.Add("@dtFim", SqlDbType.DateTime, dtFim);
pCol.Add("@CodNo", SqlDbType.VarChar, -1, CodNo);
return ExecuteDataSet(sql, pCol, SessionID, connectionTimeout);
}
catch (Exception ex)
{
logErro(ex, "DataSet RelatorioEspecializacao");
return null;
}
}
创建存储过程:
USE [YOUR DATABASE]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[store_procedure]
@SERVERNAME SYSNAME = @@SERVERNAME
, @DB SYSNAME
, @Object SYSNAME
, @Str NVARCHAR(4000);
AS
BEGIN
DECLARE
DBList CURSOR LOCAL FAST_FORWARDFOR
SELECT name FROM sys.databases;
OPEN DBList;
FETCH NEXT FROM DBList INTO @DB;
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @Str = 'SELECT name AS Tables FROM '+@DB+'.sys.tables; SELECT
TABLE_NAME AS Views FROM '+@DB+'.INFORMATION_SCHEMA.VIEWS; SELECT
ROUTINE_NAME AS StoredProcedures FROM '+@DB+'.INFORMATION_SCHEMA.ROUTINES;'
EXEC sp_executesql @StrFETCH NEXT FROM DBList INTO @DB; ENDCLOSE DBList;
END
DEALLOCATE DBList
return
END
GO