2012-06-29 8 views
5

Ich habe eine gespeicherte Prozedur, die einen Benutzer hinzufügt, und bei jeder Berechtigung, die ich hinzufüge, möchte ich mit dem Erstellen einer Erfolgsmeldung beginnen.Zurückgeben einer Nachricht aus einer gespeicherten Prozedur an C# app

Meine gespeicherte Prozedur läuft gut, aber wie bekomme ich diese Erfolgsmeldung zurück in einen Nachrichtendialog in meiner App?

Ich möchte den folgenden @text in einer Nachricht in meiner C# -App anzeigen. in meinem C# app

DECLARE @text NVARCHAR(1000) 
SET @text = 'This is line 1.' + CHAR(13)+CHAR(10) + 'This is line 2.' 
SELECT @text 

Das ist mein Aufruf:

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; 
     }  
    } 

Merk proc, konzentrieren sich nur auf Abschnitte von allen druckt, das ist der Text den ich hinzufüge:

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

Try 'MessageBox.Show (dt.Rows [0] [0] .ToString());' – adatapost

Antwort

7

Ihre beste Wette zu verwenden, ist ein Ausgabeparameter .

Fügen Sie in Ihrer gespeicherten Prozedur den Parameter @text nvarchar(1000) OUTPUT hinzu, fügen Sie dann in Ihrem Code einen zusätzlichen Parameter mit dem Namen @text hinzu und setzen Sie die Parameterrichtung auf output.

dann fügen Sie einfach die Zeile SET @text = 'This is line 1.' + CHAR(13)+CHAR(10) + 'This is line 2.' in Ihrer gespeicherten Prozedur

Edit: Meine Antwort ist, wenn Sie dies nicht möchten, dass Ihre aktuelle Abfrage beeinflussen, wenn ich Ihre Frage falsch interpretiert bitte mich wissen lassen. Auch um den Wert zu erhalten, nachdem Sie die Abfrage ausführen Sie den Wert aus dem @name Parameter erhalten kann .Wert mit

Edit 2: Beispiel-Code etwas aussehen sollte

//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 

wenn Sie Hilfe benötigen mit die gespeicherte Prozedur per Post bitte, und ich werde ein Beispiel mit diesem zu

bearbeiten 3 geben: Kurzes Beispiel getestet mit einem schnellen Beispiel.Der C# -Code:

 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(); 
      } 
     } 

Die gespeicherte Prozedur:

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 

funktionierte gut für mich, wenn Sie es gegen Ihre für Unterschiede

bearbeiten 4 überprüfen möchten: In der gespeicherten Prozedur die @text muss ein Parameter sein, also anstelle von

ALTER PROCEDURE [dbo].[AdminDevUserCreate] 
    @SQLLoginName varchar(50), 
    @SQLLoginPass varchar(50) 
AS 

DECLARE @text NVARCHAR(1000)OUTPUT 

machen es

ALTER PROCEDURE [dbo].[AdminDevUserCreate] 
    @SQLLoginName varchar(50), 
    @SQLLoginPass varchar(50), 
    @text NVARCHAR(1000) OUTPUT 
AS 

auch wenn die SqlParameter

SqlParameter text = new SqlParameter("@Text", SqlDbType.NVarChar, 1000); 

verwenden zu schaffen, die von der Größe Problem loswerden sollte, wie Sie es sagen, dass der Parameter NVARCHAR(1000)

die Linie

ist
PRINT @text 
Select @text 

sollte nicht benötigt werden

+0

Wie würde ich hinzufügen, dass Parameter gerichtet Ausgabe? Ich habe @text nvarchar (1000) OUTPUT hinzugefügt, wie bekomme ich nun meine Messagebox um es anzuzeigen? – Pomster

+0

@Pommy kann sich nicht erinnern, ob es mit SqlAdapters anders geht, aber ich denke, dass der geschriebene Code funktionieren sollte, lass es mich wissen, wenn es nicht – Manatherin

+0

Ich habe diese Nachricht, Objektreferenz nicht auf eine Instanz eines Objekts gesetzt. – Pomster

0

Ihre Datentabelle dt hat Ihre Textausgabe. Sie können

Für zB
MessageBox.Show("" + dt.Rows[0][0]); 
2

Wenn Sie MVC verwenden, dann gibt es eine ausgezeichnete Probe here. Ich habe es in mehreren Projekten verwendet und es fantastisch gefunden.

Auch sollten Sie Ihr SqlCommand und SqlConnection Objekt in die Verwendung von Anweisungen wickeln, um undichte Verbindungen zu stoppen.

Hinweis: Dies kann problemlos an WebForms angepasst werden.

1
MessageBox.Show(dt.Rows[0][0].Tostring()); 

oder

einen Ausgabeparameter verwenden

2

Informationsmeldungen aus SqlConnection.InfoMessage Ereignis abgerufen werden. Sie können in T-SQL-Code unter Verwendung von RAISERROR mit dem Schweregrad 0-9 ausgelöst werden.

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;  
     } 
    } 

Und in T-SQL:

RAISERROR(N'This is line %d', 0,0,1); 
RAISERROR(N'This is line %d', 0,0,2); 
Verwandte Themen