嘿所有我想弄清楚如何解决这个问题。我想在我的C#程序中向查询发送一个参数,该参数是我的表的名称。我已经读过这是不可能的,他们建议您制作一个存储过程来执行此操作。
所以这是我目前的代码:
CREATE PROCEDURE _tmpSP
@TableName NVARCHAR(128)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @Sql NVARCHAR(MAX);
SET @Sql = N'SELECT TOP 1 HelpMsg FROM ' + QUOTENAME(@TableName)
EXECUTE sp_executesql @Sql
DROP PROCEDURE [_tmpSP]
END
当我在Server Management Studio中执行它时,它会创建SP,但从不执行该存储过程,也不会将其删除。
当我在Server Management Studio中运行该SP时(右键单击 在可编程性> dbo._tmpSP 下并选择 >执行存储过程)并为其指定表名称,它会填充然后删除SP。这是我想要而不是必须进行2次查询的最终结果。
SP运行时的SQL查询是这个( tHelp 是表名):
USE [TTool]
GO
DECLARE @return_value int
EXEC @return_value = [dbo].[_tmpSP]
@TableName = N'tHelp'
SELECT 'Return Value' = @return_value
GO
我收到了返回的帮助消息,并返回了值0。
如何修改此SP才能执行此操作?
答案 0 :(得分:1)
只需这样做,忘记存储过程:
private final void show() {
loginSignupForm = new Form("Company", new BorderLayout());
Tabs loginSignupTabs = new Tabs();
Style loginSignupStyle = UIManager.getInstance().getComponentStyle("Tab");
prepareAndAddSignupTab(loginSignupTabs, loginSignupStyle);
prepareAndAddLoginTab(loginSignupTabs, loginSignupStyle);
loginSignupForm.add(BorderLayout.CENTER, loginSignupTabs);
loginSignupForm.show();
}
肮脏的C#......
EXECUTE sp_executesql 'SELECT TOP 1 HelpMsg FROM '+QUOTENAME(@TableName)
其中string qry = string.Format("SELECT TOP 1 HelpMSG FROM {0}", myTableName.Replace("'", "''"));
cmd = conn.CreateCommand();
cmd.CommandText = qry;
string helpMsg = conn.ExecuteScalar();
是conn
答案 1 :(得分:0)
您需要创建另一个SP来应用您的逻辑。首先让我们看看你的SP:
CREATE PROCEDURE [_tmpSP]
@TableName NVARCHAR(128)
AS
BEGIN
DECLARE @Sql NVARCHAR(MAX);
SET @Sql = N'SELECT TOP 1 HelpMsg FROM ' + @TableName
EXEC(@Sql)
END
然后,只有在返回结果后需要删除第一个SP时才创建另一个SP。逻辑将是:
Create procedure auto_delete
@NewTableName
as
begin
EXEC _tmpSP @TableName = @NewTableName
Drop procedure [_tmpSP]
End
在C#中(我假设你使用的是上面的第二个SP):
您的代码可能是这样的:
..
using System.Data.SqlClient;
..
string a = YourTableName;
using (SqlConnection sqlCon = new SqlConnection(YourDatabaseConnection))
{
sqlCon.Open()
using (SqlCommand sqlCmd = sqlCon.CreateCommand())
{
sqlCmd.CommandText = "auto_delete";
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.Parameters.Add(new SqlParameter("NewTableName", a));
sqlCmd.ExecuteNonQuery();
}
sqlCon.Close();
}
答案 2 :(得分:0)
我同意@SsJVasto。如果您仍然需要在C#程序中不对您的查询进行硬编码,则可以使用xml并将查询保留在其中。并获取xml并执行查询。我想你想处理一些动态的东西。
答案 3 :(得分:0)
这样做没有意义,因为它非常复杂,并且还会产生创建和删除存储过程的开销。如果您有一个动态查询来处理一些无法作为参数推送的动态元素,您可以构造查询字符串:
var query = $"SELECT TOP 1 col FROM {tableName}";
但是,如果基于用户输入构造tableName
,则必须注意避免SQL注入。 This question and its answers处理这个问题:
DbConnection connection = GetMyConnection();
DbProviderFactory factory = DbProviderFactories.GetFactory(connection);
DbCommandBuilder commandBuilder = factory.CreateCommandBuilder();
var tableName commandBuilder.QuoteIdentifier(rawTableName);
如果需要“普通”(非表名)参数,请在查询中照常传递它们。例如。 @ param1,@ param2