Toon posts:

[ASP.NET / C#] Kan waarde uit stored procudure niet opvangen

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo ik heb een stukje code die een stored procedure aanroept die kijkt een een huisje bezet is voor een bepaalde periode. Ik krijg als uitvoer 0 tabellen, terwijl ik zeker weet dat huisje 2325 een reservering heeft tussen 1995 en 2005.

Wat doe ik fout, wie kan me helpen?


Dit is de stored procedure sp_check_bezetting:

code:
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
83
84
85
86
87
88
89
90
91
92
93
CREATE PROC sp_check_bezetting
  @beginperiode datetime    OUTPUT,
  @eindperiode  datetime    OUTPUT,
  @huisid   int,
  @bezet    int = NULL  OUTPUT 

AS
DECLARE @isbezet int
DECLARE @begindiffa int
DECLARE @begindiffb int
DECLARE @einddiffa int
DECLARE @einddiffb int


DECLARE @periodevan datetime
DECLARE @periodetot datetime
DECLARE @nrofvalues int
DECLARE @iterator   int

SELECT @iterator = 0;
SELECT @nrofvalues = (SELECT COUNT(*) FROM bezetting WHERE huisid = @huisid)
DECLARE PeriodeCursor CURSOR FOR
SELECT periodevan, periodetot FROM bezetting WHERE huisid =@huisid


OPEN PeriodeCursor

FETCH NEXT FROM PeriodeCursor INTO @periodevan, @periodetot
  PRINT @periodevan
  PRINT @periodetot

WHILE @@FETCH_STATUS = 0
  BEGIN
  
  IF @isBezet = 1
    BREAK

  SELECT @begindiffa = DATEDIFF(d, @periodevan, @beginperiode ) 
  SELECT @begindiffb = DATEDIFF(d, @periodetot, @beginperiode ) 
  SELECT @einddiffa = DATEDIFF(d, @periodevan, @eindperiode ) 
  SELECT @einddiffb = DATEDIFF(d, @periodetot, @eindperiode ) 

  
  PRINT 'Periode bezet: ' + CONVERT(varchar(50), @periodevan) + ' tot ' + CONVERT(varchar(50), @periodetot)
  PRINT 'Gevraagde periode: ' + CONVERT(varchar(50), @beginperiode) + ' tot ' + CONVERT(varchar(50), @eindperiode)
  SELECT @isBezet = 0
  IF @begindiffa >= 0 AND @begindiffb <= 0
  BEGIN
    PRINT 'Begindatum valt binnen reservering'
    SELECT @isBezet = 1
    SELECT @bezet = @isbezet
  END
  IF @einddiffa >= 0 AND @einddiffb <=0
  BEGIN
    PRINT 'Eind datum valt binnen reservering'
    SELECT @isBezet = 1
    SELECT @bezet = @isbezet
  END
  IF @begindiffa <= 0 AND @einddiffb <= 0 AND @einddiffa >= 0
  BEGIN
    PRINT 'Begin datum valt buiten reservering, maar einddatum valt binnen reservering'
    SELECT @isBezet = 1
    SELECT @bezet = @isbezet
  END

  IF @einddiffb >= 0 AND @begindiffa >= 0 AND @begindiffb <= 0 
  BEGIN
    PRINT 'Begin datum valt binnen reservering, en de eind datum valt buiten de reservering'
    SELECT @isBezet = 1
    SELECT @bezet = @isbezet
  END

  IF @begindiffa < 0 AND @einddiffb > 0
  BEGIN
    PRINT 'Tussen de gevraagde data zit een reservering'
    SELECT @isBezet = 1
    SELECT @bezet = @isbezet

    
  END

  IF @isbezet = 0
  BEGIN
    PRINT 'Niet bezet in gevraagde periode'
    SELECT @bezet = @isbezet
  END
SELECT @iterator = @iterator + 1
FETCH NEXT FROM PeriodeCursor INTO @periodevan, @periodetot
END
CLOSE PeriodeCursor
DEALLOCATE PeriodeCursor

GO


Dit is mijn C# code:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
            SqlDataAdapter adapter = new SqlDataAdapter("sp_check_bezetting",connection);
                        
            adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
            adapter.SelectCommand.CommandText="sp_check_bezetting";

            DateTime vanaf=new DateTime(1995,01,01);
            DateTime tot=new DateTime(2005,12,31);
            int huisid=2325;
              
            adapter.SelectCommand.Parameters.Add("@beginperiode", SqlDbType.DateTime).Value = vanaf;
            adapter.SelectCommand.Parameters.Add("@eindperiode", SqlDbType.DateTime).Value = tot;
            adapter.SelectCommand.Parameters.Add("@huisid", SqlDbType.Int).Value = huisid;

            DataSet result = new DataSet();
            adapter.Fill(result);

            Response.Write(result.Tables.Count);

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Je voert alleen SELECTs uit naar een variabele, je zult dus nooit resultaat in je dataset krijgen. Alleen SELECTs die je niet naar een variabele doet krijg je in de gewone output. Als je OUTPUT parameters gebruikt moet je die ook in je C# code aanmaken, daar komt de waarde dan in te staan.

Die print statements zie je sowieso niet aan de clientkant, maar misschien is dat alleen voor debuggen gedaan.

Je gebruikt een cursor, in bijna alle gevallen is dit niet nodig. Een cursor is heel zwaar en als je er een kan voorkomen is dit beter. Post je tabel layout eens, misschien wil het best zonder cursor. Als ik het goed begrijp wil je controleren of het huis bezet is?

Ten slotte, je moet je stored procs nopoit prefixen met sp_ , dit is een prefix die voor system stored procs gebruikt word, en sql server kijkt als allereerste in de master database naar deze proc, dit kost ook weer wat tijd.

Oops! Google Chrome could not find www.rijks%20museum.nl


  • stp_4
  • Registratie: Maart 2003
  • Laatst online: 30-04 19:47
Kon je je sp niet wat inkorten? Heb je het al geprobeerd in je queryanalyser? Probeer afzonderlijke queries te testen..

stp - PSN ID: stp_4


Verwijderd

Topicstarter
Ok, tnx voor de info.

Ik wil graag eerst dat het werkt, dan kan het daarna nog wel wat verbeteren met die punten die je aangeeft.

Als ik het goed begrijp moet ik in m'n code een output variabele opzetten..

Ik heb nu deze regels code toegevoegd:

code:
1
2
3
4
            adapter.SelectCommand.Parameters.Add("@isbezet",SqlDbType.Int);
            adapter.SelectCommand.Parameters["@isbezet"].Direction = ParameterDirection.Output;

            string bezet=adapter.SelectCommand.Parameters["@isbezet"].Value.ToString();


Maar nu krijg ik de volgende error:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
Object reference not set to an instance of an object. 
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error: 


Line 36:            adapter.SelectCommand.Parameters["@isbezet"].Direction = ParameterDirection.Output;
Line 37: 
Line 38:            string bezet=adapter.SelectCommand.Parameters["@isbezet"].Value.ToString();
Line 39: 
Line 40:

  • stp_4
  • Registratie: Maart 2003
  • Laatst online: 30-04 19:47
C#:
1
2
3
4
SqlParameter oParam = adapter.SelectCommand.Parameters.Add("@isBezet", SqlDbType.Int);
oParam.Direction = ParameterDirection.Output;

string bezet = oParam.Value.ToString();


edit:

lijkt inderdaad hetzelfde, maar ik zie niet dat je @isBezet als een output parameter gedefinieerd is in je sp of wel? ( isBezet duidt eigenlijk eerder op een boolean/bit dan op een integer )

[ Voor 78% gewijzigd door stp_4 op 05-05-2005 14:17 ]

stp - PSN ID: stp_4


  • sig69
  • Registratie: Mei 2002
  • Laatst online: 22:24
Wat wil je nu eigenlijk als resultaat uit deze SP?

Roomba E5 te koop


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 22:49

curry684

left part of the evil twins

Je hoeft geen output variabele te definieren zolang je alleen tables als output wil: daarvoor kun je gewoon 'open' selects uitvoeren:
SQL:
1
2
3
create procedure MyProcedure
as
  select * from table;

Dit zal gewoon de hele tabel 'table' als output van de procedure geven.

Je hoort trouwens de prefix 'sp_' niet voor SP's te gebruiken, die prefix is protected voor system SP's en verneuken de lookups waardoor ie trager uitgevoerd wordt.

Professionele website nodig?


  • stp_4
  • Registratie: Maart 2003
  • Laatst online: 30-04 19:47
curry684 schreef op donderdag 05 mei 2005 @ 16:24:
Je hoeft geen output variabele te definieren zolang je alleen tables als output wil: daarvoor kun je gewoon 'open' selects uitvoeren:
Maar als op deze manier een output parameter in je code definieerd,
C#:
1
2
SqlParameter oParam = adapter.SelectCommand.Parameters.Add("@isBezet", SqlDbType.Int); 
oParam.Direction = ParameterDirection.Output;

dan geeft dat toch aan dat hij de de outputparameter @isBezet teruggeeft vanuit z'n SP? Als je het op deze wijze doet, hoef je dan nog steeds niet expliciet @isBezet als output parameter definieren in je SP?

[ Voor 4% gewijzigd door stp_4 op 05-05-2005 16:54 ]

stp - PSN ID: stp_4


Verwijderd

Topicstarter
In de code van m'n SP (In m'n eerste post) kan je zien dat ik @bezet als output variabel definieer..

nu heb de volgende c# code:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
            SqlDataAdapter adapter = new SqlDataAdapter("sp_check_bezetting",connection);
                        
            adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
            adapter.SelectCommand.CommandText="sp_check_bezetting";

            DateTime vanaf=new DateTime(1995,01,01);
            DateTime tot=new DateTime(2005,12,31);
            int huisid=2325;
              
            adapter.SelectCommand.Parameters.Add("@beginperiode", SqlDbType.DateTime).Value = vanaf;
            adapter.SelectCommand.Parameters.Add("@eindperiode", SqlDbType.DateTime).Value = tot;
            adapter.SelectCommand.Parameters.Add("@huisid", SqlDbType.Int).Value = huisid;
            adapter.SelectCommand.Parameters.Add("@bezet",SqlDbType.Int);
            adapter.SelectCommand.Parameters["@bezet"].Direction = ParameterDirection.Output;

            int bezet=int.Parse(adapter.SelectCommand.Parameters["@bezet"].Value.ToString());

            Response.Write(bezet.ToString());


Maar nu krijg ik de volgende error op regel 38:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
Object reference not set to an instance of an object. 
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error: 


Line 36:            adapter.SelectCommand.Parameters["@bezet"].Direction = ParameterDirection.Output;
Line 37: 
Line 38:            int bezet=int.Parse(adapter.SelectCommand.Parameters["@bezet"].Value.ToString());
Line 39: 
Line 40:            Response.Write(bezet.ToString());


Iemand enig idee wat ik nu fout doe? Bezet moet in dit geval 1 terug geven.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 22:49

curry684

left part of the evil twins

stp_4 schreef op donderdag 05 mei 2005 @ 16:53:
[...]


Maar als op deze manier een output parameter in je code definieerd,
C#:
1
2
SqlParameter oParam = adapter.SelectCommand.Parameters.Add("@isBezet", SqlDbType.Int); 
oParam.Direction = ParameterDirection.Output;

dan geeft dat toch aan dat hij de de outputparameter @isBezet teruggeeft vanuit z'n SP? Als je het op deze wijze doet, hoef je dan nog steeds niet expliciet @isBezet als output parameter definieren in je SP?
Daarmee definieer je gewoon een returnwaarde van het type int, varieert van de SP of het wel of niet gewenst is. Tables kun je net zo goed via de reguliere results teruggeven :)
Verwijderd schreef op donderdag 05 mei 2005 @ 18:20:
Maar nu krijg ik de volgende error op regel 38:

[...]

Iemand enig idee wat ik nu fout doe? Bezet moet in dit geval 1 terug geven.
Nogal wiedes dat daar een NULL in staat als je de SP niet eerst uitvoert he?

Professionele website nodig?


Verwijderd

Topicstarter
|:(

dat was het ja.. en nog connection.open();
nu is het gelukt, tnx voor de hulp
Pagina: 1