我有一个添加用户的存储过程,在我添加的每个权限中,我想开始构建成功消息。
我的存储过程运行正常,但如何将该成功消息重新发送回我的应用中的消息对话框?
我想在我的C#app中的消息框中显示以下@text。
DECLARE @text NVARCHAR(1000)
SET @text = 'This is line 1.' + CHAR(13)+CHAR(10) + 'This is line 2.'
SELECT @text
这是我在C#app中的电话:
public DataTable CreateOrDropUser(string dataBase, string procedure, SqlParameter[] parameters)
{
try
{
if (dataBase.Length > 0) { procedure = dataBase + ".." + procedure; } //Set procedure to DBNAME..ProcedureName
SqlCommand cmd1 = new SqlCommand(procedure, con);
cmd1.CommandType = CommandType.StoredProcedure;
foreach (SqlParameter p in parameters)
{
if (p != null)
{
cmd1.Parameters.Add(p);
}
}
con.Open();
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd1);
da.Fill(dt);
con.Close();
MessageBox.Show("Success"); //This should display the @text variable in my proc
return dt;
}
catch (Exception ex)
{
try
{
if (con.State == ConnectionState.Open)
{
con.Close();
}
}
catch
{
MessageBox.Show("Could not connect to database. Check settings. " + ex.Message, "Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
MessageBox.Show(ex.Message);
return null;
}
}
我的存储过程,只关注所有打印的部分,这是我正在添加的文字:
ALTER PROCEDURE [dbo].[AdminDevUserCreate]
@SQLLoginName varchar(50),
@SQLLoginPass varchar(50)
AS
DECLARE @text NVARCHAR(1000)OUTPUT
--PRINT 'Create SQL Login'
SET @text = 'Create SQL Login ' + @SQLLoginName
-- USE [Master]
EXEC(' USE [master] CREATE LOGIN [' + @SQLLoginName + '] WITH PASSWORD=''' + @SQLLoginPass + ''', DEFAULT_DATABASE=[TestAudit], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF')
--PRINT 'Add Server Roles'
SET @text += + CHAR(13)+CHAR(10) + 'Add Server Roles'
--Add Server roles
EXEC master..sp_addsrvrolemember @loginame = @SQLLoginName, @rolename = N'bulkadmin'
EXEC master..sp_addsrvrolemember @loginame = @SQLLoginName, @rolename = N'processadmin'
EXEC master..sp_addsrvrolemember @loginame = @SQLLoginName, @rolename = N'securityadmin'
--PRINT 'Allow SQL Agent Job Manage'
SET @text += + CHAR(13)+CHAR(10) + 'Allow SQL Agent Job Manage'
--USE [MSDB]
EXEC ('msdb..sp_addrolemember ''SQLAgentOperatorRole'', ''' + @SQLLoginName + '''')
--PRINT 'Allow Trace'
SET @text += + CHAR(13)+CHAR(10) + 'Allow Trace'
--Allow trace (SQL Profiler)
--USE [MASTER]
EXEC (' USE [MASTER] GRANT ALTER TRACE TO ' + @SQLLoginName )
--PRINT 'Prevent admin proc changes '
SET @text += + CHAR(13)+CHAR(10) + 'Prevent admin proc changes '
EXEC ('USE [TestAudit] DENY ALTER ON [TestAudit].[dbo].[Admin] TO ' + @SQLLoginName) --Prevents changes to Admin function
--PRINT 'Prevent database trigger changes'
SET @text += + CHAR(13)+CHAR(10) + 'Prevent database trigger changes'
EXEC ('USE [TestAudit] DENY ALTER ANY DATABASE DDL TRIGGER TO ' + @SQLLoginName) --Prevents modify of [SchemaAuditTrigger]
PRINT @text
Select @text
答案 0 :(得分:7)
最好的办法是使用输出参数。
在存储过程中添加参数@text nvarchar(1000) OUTPUT
然后在代码中添加名为@text
的额外参数,并将参数方向设置为output
。
然后只需在存储过程中添加行SET @text = 'This is line 1.' + CHAR(13)+CHAR(10) + 'This is line 2.'
编辑:我的回答是,如果您不希望这会影响您当前的查询,如果我误解了您的问题,请告知我们。另外,要获取值,执行查询后,您可以使用.Value
从@name
参数中获取值。
编辑2:示例代码应该看起来像
//Add these lines
SqlParameter text = new SqlParameter("@name", SqlDbType.NVarChar);
text.Direction = ParameterDirection.Output;
cmd1.Parameters.Add(text);
con.Open();
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd1);
da.Fill(dt);
con.Close();
//Change this line
MessageBox.Show(text.Value); //This should display the @text variable in my proc
如果您需要有关存储过程的帮助,请发布它,我也会举一个例子
编辑3:快速示例使用快速示例进行测试。 C#代码:
using (SqlConnection connection = new SqlConnection(@"Data Source=.\SQLExpress;Initial Catalog=TestDB;Integrated Security=True"))
{
connection.Open();
using (SqlCommand command = connection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "Test";
SqlParameter text = new SqlParameter("@Text", SqlDbType.NVarChar, 1000);
text.Direction = ParameterDirection.Output;
command.Parameters.Add(text);
using (DataTable dt = new DataTable())
{
using (SqlDataAdapter da = new SqlDataAdapter(command))
{
da.Fill(dt);
}
}
Trace.WriteLine(text.Value);
connection.Close();
}
}
存储过程:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE Test
@Text Nvarchar(1000) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET @Text = 'test'
END
GO
如果你想与你的差异进行检查,那么对我来说工作正常
编辑4:在您的存储过程中,@ text需要是一个参数,而不是
ALTER PROCEDURE [dbo].[AdminDevUserCreate]
@SQLLoginName varchar(50),
@SQLLoginPass varchar(50)
AS
DECLARE @text NVARCHAR(1000)OUTPUT
制作
ALTER PROCEDURE [dbo].[AdminDevUserCreate]
@SQLLoginName varchar(50),
@SQLLoginPass varchar(50),
@text NVARCHAR(1000) OUTPUT
AS
在创建SqlParameter时也使用
SqlParameter text = new SqlParameter("@Text", SqlDbType.NVarChar, 1000);
应该摆脱尺寸问题,因为你告诉它参数是NVARCHAR(1000)
行
PRINT @text
Select @text
不应该
答案 1 :(得分:2)
如果您正在使用MVC,那么有一个很好的样本here。我在多个项目中使用它并发现它非常棒。
此外,您应该将SqlCommand
和SqlConnection
对象用于使用语句来阻止泄漏连接。
注意:这可以适应WebForms而不会有太多麻烦。
答案 2 :(得分:2)
可以从SqlConnection.InfoMessage
事件中检索信息性消息。可以使用严重性为0-9的RAISERROR
在T-SQL代码中引发它们。
public DataTable CreateOrDropUser(string dataBase, string procedure, SqlParameter[] parameters)
{
SqlconnecitonStringBuilder scsb = new SqlConnectionStringBuilder (connstring);
scsb.Database = database;
using (SqlConnection con = new SqlConnection (scsb.ConnectionString))
{
StringBuilder sb = new StringBuilder ();
con.Open ();
SqlCommand cmd1 = new SqlCommand(procedure, con);
cmd1.CommandType = CommandType.StoredProcedure;
foreach (SqlParameter p in parameters)
{
if (p != null)
{
cmd1.Parameters.Add(p);
}
}
conn.InfoMessage += (args =>
{
sb.AppendLine (args.Message);
});
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd1);
da.Fill(dt);
MessageBox.Show(sb);
return dt;
}
}
在T-SQL中:
RAISERROR(N'This is line %d', 0,0,1);
RAISERROR(N'This is line %d', 0,0,2);
答案 3 :(得分:1)
MessageBox.Show(dt.Rows[0][0].Tostring());
或
使用输出参数
答案 4 :(得分:0)
您的数据表dt包含您的文本输出。您可以 例如
MessageBox.Show("" + dt.Rows[0][0]);