Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 Development Tools
 ASP.NET
 Calling crosstab stored proc from C#

Author  Topic 

don_t
Starting Member

7 Posts

Posted - 2005-03-21 : 13:43:05
I am calling the crosstab stored proc in http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=6216 from a C# program.

I'm wondering if there are any issues with calling this crosstab stored proc from C#. When run from a C# program I keep getting the message: Incorrect syntax near the keyword 'END'.

When run directly from SQL Query Analyzer or Server Explorer it works fine, so I'm not sure how to debug this problem.

spirit1
Cybernetic Yak Master

11752 Posts

Posted - 2005-03-21 : 13:51:52
how are you calling the stored procedure from c#?

Go with the flow & have fun! Else fight the flow
Go to Top of Page

don_t
Starting Member

7 Posts

Posted - 2005-03-21 : 14:17:21
Originally I passed a parameter in the stored proc but removed it for debugging. So the C# code looks like:


try
{
SqlCommand cmd = new SqlCommand("SP_TEST_GET_SURVEY", conn);
cmd.CommandType = CommandType.StoredProcedure;

conn.Open();
SqlDataReader reader = cmd.ExecuteReader(); // SqlException thrown here

...
}
catch (SqlException e)
{
Console.WriteLine(e.Message);
}



The SP_TEST_GET_SURVEY stored proc is somewhat messy but listed below. Its just the crosstab stored proc with hardcoded test data. It seems to fail at the EXEC (@select) line when called from the C# code above.


CREATE PROCEDURE SP_TEST_GET_SURVEY AS

DECLARE @select varchar(8000)
DECLARE @sumfunc varchar(100)
DECLARE @pivot varchar(100)
DECLARE @table varchar(100)

SET @select = 'SELECT VW_ALL_SURVEYS.[Project Manager ID] '
SET @select = @select + 'FROM VW_ALL_SURVEYS '
SET @select = @select + 'WHERE VW_ALL_SURVEYS.[Project Manager ID] = ' + CAST(15 AS VARCHAR(12)) + ' '
SET @select = @select + 'GROUP BY VW_ALL_SURVEYS.[Project Manager ID]'

SET @sumfunc = 'min([PCT Manager])'
SET @pivot = 'VW_ALL_SURVEYS.Role'
SET @table = 'VW_ALL_SURVEYS'

DECLARE @sql varchar(8000), @delim varchar(1)
SET NOCOUNT ON
SET ANSI_WARNINGS OFF

EXEC ('SELECT ' + @pivot + ' AS pivot INTO ##pivot FROM ' + @table + ' WHERE 1=2')
EXEC ('INSERT INTO ##pivot SELECT DISTINCT ' + @pivot + ' FROM ' + @table + ' WHERE '
+ @pivot + ' Is Not Null')

SELECT @sql='', @sumfunc=stuff(@sumfunc, len(@sumfunc), 1, ' END)' )

SELECT @delim=CASE Sign( CharIndex('char', data_type)+CharIndex('date', data_type) )
WHEN 0 THEN '' ELSE '''' END
FROM tempdb.information_schema.columns
WHERE table_name='##pivot' AND column_name='pivot'

SELECT @sql=@sql + '''' + convert(varchar(100), pivot) + ''' = ' +
stuff(@sumfunc,charindex( '(', @sumfunc )+1, 0, ' CASE ' + @pivot + ' WHEN '
+ @delim + convert(varchar(100), pivot) + @delim + ' THEN ' ) + ', ' FROM ##pivot

DROP TABLE ##pivot

SELECT @sql=left(@sql, len(@sql)-1)
SELECT @select=stuff(@select, charindex(' FROM ', @select)+1, 0, ', ' + @sql + ' ')

PRINT @select

EXEC (@select)


SET ANSI_WARNINGS ON
GO
Go to Top of Page

tkizer
Almighty SQL Goddess

38200 Posts

Posted - 2005-03-21 : 14:23:31
So when you run this in Query Analyzer, it doesn't fail:

EXEC dbo.SP_TEST_GET_SURVEY

??

Please post the results from Query Analyzer. If it worked, it should have printed @select. Also, you should comment out the PRINT statement when you are done debugging inside Query Analyzer.

Tara
Go to Top of Page

don_t
Starting Member

7 Posts

Posted - 2005-03-21 : 14:37:33
Yes it works fine with Query Analyzer or Server Explorer. The select query is:

SELECT VW_ALL_SURVEYS.[Project Manager ID] , 'Manager' = min( CASE VW_ALL_SURVEYS.Role WHEN 'Manager' THEN [PCT Manager] END), 'PM' = min( CASE VW_ALL_SURVEYS.Role WHEN 'PM' THEN [PCT Manager] END) FROM VW_ALL_SURVEYS WHERE VW_ALL_SURVEYS.[Project Manager ID] = 15 GROUP BY VW_ALL_SURVEYS.[Project Manager ID]

I guess I could call the SELECT query directly from the C# program but might be useful to know why this weird behavior is happening.
Go to Top of Page

spirit1
Cybernetic Yak Master

11752 Posts

Posted - 2005-03-22 : 05:17:55
could it be that you have a stored procedure with the same name in your master database which does nothing?
because you have yours prefixed with sp_ and that means that the parser goes first to master db to look it up.

Go with the flow & have fun! Else fight the flow
Go to Top of Page

don_t
Starting Member

7 Posts

Posted - 2005-03-22 : 13:26:51
I believe I've solved the problem though no idea still what caused it. For some reason the @delim variable in the crosstab stored proc is null when called from Visual C#. So I set @delim to single quote if IsNull. The new stored proc is listed here if anyone cares.



CREATE PROCEDURE SP_CROSSTAB
@select varchar(8000),
@sumfunc varchar(100),
@pivot varchar(100),
@table varchar(100)
AS

DECLARE @sql varchar(8000), @delim varchar(1)
SET NOCOUNT ON
SET ANSI_WARNINGS OFF

EXEC ('SELECT ' + @pivot + ' AS pivot INTO ##pivot FROM ' + @table + ' WHERE 1=2')
EXEC ('INSERT INTO ##pivot SELECT DISTINCT ' + @pivot + ' FROM ' + @table + ' WHERE '
+ @pivot + ' Is Not Null')

SELECT @sql='', @sumfunc=stuff(@sumfunc, len(@sumfunc), 1, ' END)' )

SELECT @delim=CASE Sign( CharIndex('char', data_type)+CharIndex('date', data_type) )
WHEN 0 THEN '' ELSE '''' END
FROM tempdb.information_schema.columns
WHERE table_name='##pivot' AND column_name='pivot'

/* @delim may be null if user lacks appropriate access rights to tempdb */
SELECT @delim = IsNull(@delim, '''')


SELECT @sql=@sql + '''' + convert(varchar(100), pivot) + ''' = ' +
stuff(@sumfunc,charindex( '(', @sumfunc )+1, 0, ' CASE ' + @pivot + ' WHEN '
+ @delim + convert(varchar(100), pivot) + @delim + ' THEN ' ) + ', ' FROM ##pivot

DROP TABLE ##pivot

SELECT @sql=left(@sql, len(@sql)-1)
SELECT @select=stuff(@select, charindex(' FROM ', @select)+1, 0, ', ' + @sql + ' ')

EXEC (@select)
SET ANSI_WARNINGS ON
GO
Go to Top of Page

jen
Master Smack Fu Yak Hacker

4110 Posts

Posted - 2005-04-07 : 03:18:41
null + SomeString = null

--------------------
keeping it simple...
Go to Top of Page

jhermiz

3564 Posts

Posted - 2005-04-07 : 10:27:38
try setting a default to your parameters in your stored procedure, that is your main problem.


Keeping the web experience alive -- [url]http://www.web-impulse.com[/url]
Imperfection living for perfection --
[url]http://jhermiz.blogspot.com/[/url]
Go to Top of Page

don_t
Starting Member

7 Posts

Posted - 2005-04-08 : 11:39:10
What's really perplexing to me is not the stored procedure itself, but the fact that the same stored procedure behaves one way when called from Visual C#, and differently from Query Analyzer or Server Explorer.
Go to Top of Page

jhermiz

3564 Posts

Posted - 2005-04-08 : 13:18:08
Did you run profiler to see whats being sent from C# ?


Keeping the web experience alive -- [url]http://www.web-impulse.com[/url]
Imperfection living for perfection --
[url]http://jhermiz.blogspot.com/[/url]
Go to Top of Page

tkizer
Almighty SQL Goddess

38200 Posts

Posted - 2005-04-08 : 13:19:59
quote:
Originally posted by don_t

What's really perplexing to me is not the stored procedure itself, but the fact that the same stored procedure behaves one way when called from Visual C#, and differently from Query Analyzer or Server Explorer.




The stored procedure isn't what's behaving differently, it's what you are passing to it that is causing different results. As Jon suggested, run SQL Profiler to determine what you are passing to it and compare that to what you are using in Query Analyzer.

Tara
Go to Top of Page

don_t
Starting Member

7 Posts

Posted - 2005-04-08 : 14:31:46
Ok, well the problem is not parameters (I created a test stored procedure with no parameters), C# or Query Analyzer. I was using different logins on Visual C# and Query Analyzer. I get same incorrect syntax error now on SqlClient and Query Analyzer when login with the same SQL Server user (role=public). When I login with that user, @delim=null after the stored procedure hits the SELECT below. When I login with Windows authentication, @delim = ''''.

SELECT @delim=CASE Sign( CharIndex('char', data_type)+CharIndex('date', data_type) )
WHEN 0 THEN '' ELSE '''' END
FROM tempdb.information_schema.columns
WHERE table_name='##pivot' AND column_name='pivot'

Probably some issue with the public user selecting from tempdb.information_schema.
Go to Top of Page

don_t
Starting Member

7 Posts

Posted - 2005-04-08 : 16:08:17
Ok the real problem and solution is described here http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=6216&whichpage=3

quote:
Originally posted by robvolk

You need to have CREATE TABLE rights in tempdb, and SELECT permissions on any table(s) that would be included in the cross tab. The tempdb part shouldn't be a problem, you can test it easily with CREATE TABLE ##temp and DROP TABLE ##temp. If either of those throw errors, you'd have to get that fixed. You might also need to have them set the "select into/bulk copy" option to "on" for tempdb, they might've forgotten to set it (or came up with a really dumb reason to turn it off)





Changing access rights is not something I can control so I added the hack SELECT @delim = IsNull(@delim, '''') to the stored procedure and seems to work for me.
Go to Top of Page
   

- Advertisement -