Hoe kan ik een oracle DBMS_ALERT gebruiken in mijn C# app?

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • BasSpruit
  • Registratie: September 2002
  • Laatst online: 09-04-2022
Ik heb op mijn werk een Oracle Database server. Daar kan ik vanuit visual studio naar toe connecten (server browser), ik kan daar via EF data uit ophalen. Geen enkel probleem. Er is echter ook een alert waar ik me op wil subscriben en daar ga ik de mist in.

vanuit Toad kan ik op de server dit alert aftrappen met
SQL:
1
2
3
4
BEGIN
   dbms_alert.signal('MIJNKANAAL', 'BERICHT');
END;
Commit;


Nu heb ik voorbeelden gevonden waarmee ik naar dat event zou kunnen luisteren. Ik krijg hier geen foutmeldingen, maar ik krijg ook geen alert. Dit is mijn code:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
private void Listen()
        {
            if (IsDisposed)
            {
                throw new ObjectDisposedException(nameof(OracleDatabaseListener));
            }

            string channelName = channel;

            try
            {

                OracleConnectionStringBuilder builder = new OracleConnectionStringBuilder();
                builder.DataSource = "<redacted>";
                builder.Password = "<redacted>";
                builder.PersistSecurityInfo = true;
                builder.UserID = "<redacted>";

                Console.WriteLine("connection to: '{0}'", builder.ToString());

                connection = new OracleConnection(builder.ToString());
                connection.Open();

                using (var transaction = connection.BeginTransaction())
                using (var command = connection.CreateCommand())
                {
                    Console.WriteLine($"begin alert register for channel '{channelName}'");

                    command.CommandText = $"begin sys.dbms_alert.register('{channelName}'); end;";
                    command.CommandType = CommandType.Text;
                    command.Transaction = transaction;
                    command.Prepare();
                    command.ExecuteNonQuery();

                    transaction.Commit();
                }

                while (!shouldStop)
                {
                    using (var transaction = connection.BeginTransaction())
                    using (var command = connection.CreateCommand())
                    {
                        Console.WriteLine("alert wait one");

                        command.CommandText = $"begin dbms_alert.waitone('{channelName}', :message, :status, 5); end;";
                        command.CommandType = CommandType.Text;

                        string oracleMessage = "";
                        int oracleStatus = 0;

                        var messageParameter = command.Parameters.Add("message", OracleDbType.Varchar2, 256, oracleMessage, ParameterDirection.Output);
                        var statusParameter = command.Parameters.Add("status", OracleDbType.Int32, 256, oracleStatus, ParameterDirection.Output);


                        command.Transaction = transaction;
                        command.Prepare();
                        command.ExecuteNonQuery();
                        transaction.Commit();

                        OracleString message = (OracleString)messageParameter.Value;
                        OracleDecimal status = (OracleDecimal)statusParameter.Value;

                        if (status.IsZero)
                        {
                            OnMessageRecieved(message.Value);
                        }
                        else
                        {
                            Console.WriteLine($"Alert listener warning: '{status.Value}'");
                        }

                    }

                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Trace.TraceError(ex.Message);
            }
        }
.
...

Relevante software en hardware die ik gebruik:
Visual studio 2015 pro update 3
EF 6.x
Oracle.ManagedDataAccess 12.2
Oracle.ManagedDataAccess.EntityFramework 12.2
Toad 9.5
...

Wat ik al gevonden of geprobeerd heb
...
Ik heb geprobeerd dit in een aparte thread (background) te draaien, ik heb met de while loop zitten spelen en ik heb nog wat andere regels code heen en weer geschoven. Foutmeldingen krijg ik niet.

Alle reacties


Acties:
  • 0 Henk 'm!

  • BasSpruit
  • Registratie: September 2002
  • Laatst online: 09-04-2022
als ik het eerste stuk C# code vervang door
C#:
1
2
3
4
5
6
7
8
9
10
11
string registerQuery = $"begin sys.dbms_alert.register('{channelName}'); end;";

                using (var transaction = connection.BeginTransaction())
                using (var command = new OracleCommand(registerQuery, connection))
                {
                    Console.WriteLine($"begin alert register for channel '{channelName}'");

                    command.ExecuteNonQuery();

                    transaction.Commit();
                }


en in een volgend stuk code
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
                string waitQuery = $"begin dbms_alert.waitone('{channelName}', :message, :status, 5); end;";

                while (!shouldStop)
                {
                    using (var transaction = connection.BeginTransaction())
                    using (var command = new OracleCommand(waitQuery, connection))
                    {
                        Console.WriteLine("alert wait one");

                        string oracleMessage = "";
                        int oracleStatus = 0;

                        var messageParameter = command.Parameters.Add("message", OracleDbType.Varchar2, 256, oracleMessage, ParameterDirection.Output);
                        var statusParameter = command.Parameters.Add("status", OracleDbType.Int32, 256, oracleStatus, ParameterDirection.Output);


                        command.Transaction = transaction;
                        command.Prepare();
                        command.ExecuteNonQuery();
                        transaction.Commit();


Dan werkt het dus wel