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 |
 |
|
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 ASDECLARE @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 ONSET ANSI_WARNINGS OFFEXEC ('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 ##pivotDROP TABLE ##pivotSELECT @sql=left(@sql, len(@sql)-1)SELECT @select=stuff(@select, charindex(' FROM ', @select)+1, 0, ', ' + @sql + ' ')PRINT @selectEXEC (@select)SET ANSI_WARNINGS ONGO |
 |
|
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 |
 |
|
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. |
 |
|
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 |
 |
|
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) ASDECLARE @sql varchar(8000), @delim varchar(1)SET NOCOUNT ONSET ANSI_WARNINGS OFFEXEC ('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 ##pivotDROP TABLE ##pivotSELECT @sql=left(@sql, len(@sql)-1)SELECT @select=stuff(@select, charindex(' FROM ', @select)+1, 0, ', ' + @sql + ' ')EXEC (@select)SET ANSI_WARNINGS ONGO |
 |
|
jen
Master Smack Fu Yak Hacker
4110 Posts |
Posted - 2005-04-07 : 03:18:41
|
null + SomeString = null--------------------keeping it simple... |
 |
|
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] |
 |
|
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. |
 |
|
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] |
 |
|
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 |
 |
|
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. |
 |
|
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=3quote: 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. |
 |
|
|