我正在VB.Net中开发一个程序,该程序使用LINQ与数据库连接。现在,我正在尝试从数据库中的以下存储过程中获取数据:
CREATE PROCEDURE dbo.GetTableColumn(
@ColName VARCHAR(MAX),
@TblName VARCHAR(MAX),
@Result BIT OUT
) AS
BEGIN
IF (EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TblName AND COLUMN_NAME = @ColName))
BEGIN
DECLARE @SQL VARCHAR(MAX)
SET @SQL = 'SELECT ' + @ColName + ' FROM ' + @TblName
EXEC (@SQL)
SET @Result = 1
END
ELSE
SET @RESULT = 0
RETURN @Result
END
该过程的目标是,我可以发送一个列名和一个表名作为变量,如果该列存在于表中,则返回表中的数据。
我已将过程添加到DataLinqContext中,这是引用该过程的代码:
Public Function GetTableColumn(ByVal col As String, ByVal table As String) As AutoCompleteStringCollection
GetTableColumn = New AutoCompleteStringCollection
Using dbContext As New Customer_LINQDataContext
Dim result As Boolean
Dim query = dbContext.GetTableColumn(col, table, result)
MessageBox.Show(query.ToString())
End Using
End Function
现在,我进入“消息框”对话框来测试输出数据。但是,每次运行该方法时,结果始终为1
或0
。我永远无法获得要查询的实际数据。
那么我在这里做错了什么,如何解决?
编辑:我在Database Admin Stack Exchange上问过,看看那里是否有人可以提供任何帮助。我得到了以下希望对您有帮助的答案,但我仍然不确定如何解决该问题。
您的代码正在存储过程的末尾获取RETURN @result的结果。所需的结果作为ResultSet从存储过程中传递出去。您需要使用DataReader对象来查看行。
我不确定如何使用Linq做到这一点。希望您会在StackOverflow问题上得到更好的答案。
答案 0 :(得分:0)
当sp在执行时没有错误时,通常使用存储过程返回代码0 ...为了获取记录集,如果sp没有找到表/列,我将使第3个参数无效并返回1:
CREATE PROCEDURE dbo.GetTableColumn(
@ColName VARCHAR(MAX),
@TblName VARCHAR(MAX)
) AS
BEGIN
IF (EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TblName AND COLUMN_NAME = @ColName))
BEGIN
DECLARE @SQL VARCHAR(MAX)
SET @SQL = 'SELECT ' + @ColName + ' FROM ' + @TblName
EXEC (@SQL)
END
ELSE
RETURN 1
END
在您的代码中...只需使用:
Dim query = dbContext.GetTableColumn(col, table)
答案 1 :(得分:0)
因此,要获得我想要的东西,我基本上必须停止使用Linq,因为我找不到任何使它工作的方法。我对该程序进行了一些修改,现在看起来像这样:
CREATE PROCEDURE dbo.GetTableColumn(
@ColName VARCHAR(25),
@TblName VARCHAR(25)
) AS
BEGIN
IF (EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TblName AND COLUMN_NAME = @Col_Name))
BEGIN
DECLARE @SQL VARCHAR(MAX)
SET @SQL = 'SELECT ' + @ColName + ' FROM ' + @TblName + ' WHERE ' + @ColName + ' IS NOT NULL'
EXEC (@SQL)
END
ELSE
RETURN 1
END
在那之后,我在VB.Net程序中添加了以下方法:
Public Function ExecuteCMD(ByRef CMD As SqlCommand) As DataSet
Dim DS As New DataSet()
Try
OpenDBConnection() 'Custom class to open the DB Connection'
CMD.Connection = DB_CONNECTION 'Private member set to db connection on initialization'
If CMD.CommandText.Contains(" ") Then
CMD.CommandType = CommandType.Text
Else
CMD.CommandType = CommandType.StoredProcedure
End If
Dim adapter as New SqlDataAdapter(CMD)
adapter.SelectCommand.CommandTimeout = 300
adapter.Fill(DS)
CloseDBConnection 'Custom class to close DB Connection'
Catch ex As Exception
Throw New Exception("Database Error: " & ex.Message)
End Try
Return DS
End Function
此方法归功于Brian Webster here。大量的代码对使它起作用很有帮助。最后,我修改了GetTableColumn
方法,使其看起来像这样:
Public Function GetTableColumn(ByVal col As String, ByVal table As String) As AutoCompleteStringCollection
GetTableColumn = New AutoCompleteStringCollection
Dim CMD As New SqlCommand("GetTableColumn")
CMD.Parameters.Add("@ColName", SqlDbType.VarChar).Value = col
CMD.Parameters.Add("@TblName", SqlDbType.VarChar).Value = table
Dim DS As DataSet = ExecuteCMD(CMD)
For Each DR As DataRow In DS.Tables(0).Rows
If Not IsNothing(DR(0)) Then GetTableColumn.Add(CStr(DR(0)))
Next
End Function
此设置可为我提供所需的结果,并且不会像LINQ那样使我痛苦不已,因此,如果其他人遇到与我相同的问题,我会在此发布此信息。如果沟渠LINQ开始令人沮丧,那是不值得的。