|

Introduction
Ever got fed up with creating all the code behind parameters for your stored procedures? I have. So, I wrote this stored proc to do the code for me. (I love code that writes code). This has been written for use with "Microsoft Data Application Block" (SQLHelper.cs), however it could be hacked around to write the code without using the MDAB or even to write the code in VB. The script handles both input and output parameters, setting the size of text types, and you could even use it for direct access to a view or table.
Using the code
To implement, just copy the code into Query Analyzer and run. This will create a SPROC called "tools_CS_SPROC_Builder".
To use, just execute the SPROC passing the name of the SPROC you want the code for (see below). Note: don't include any owner prefix, e.g.: (dbo.). EXEC tools_CS_SPROC_Builder 'mySprocsNameHere'
The message window in the Query Analyzer will write out all the code required for your class or code behind. There is a variable in "tools_CS_SPROC_Builder" called "@connName" which you can set to the name of your connection instance. By default, it's set to "conn.Connection" - just alter this for your own project's naming convention.
The codeCREATE PROCEDURE tools_CS_SPROC_Builder
(
@objName nvarchar(100)
)
AS
SET NOCOUNT ON
DECLARE @parameterCount int
DECLARE @errMsg varchar(100)
DECLARE @parameterAt varchar(1)
DECLARE @connName varchar(100)
//Change the following variable to the name of your connection instance
SET @connName='conn.Connection'
SET @parameterAt=''
SELECT
dbo.sysobjects.name AS ObjName,
dbo.sysobjects.xtype AS ObjType,
dbo.syscolumns.name AS ColName,
dbo.syscolumns.colorder AS ColOrder,
dbo.syscolumns.length AS ColLen,
dbo.syscolumns.colstat AS ColKey,
dbo.systypes.xtype
INTO #t_obj
FROM
dbo.syscolumns INNER JOIN
dbo.sysobjects ON dbo.syscolumns.id = dbo.sysobjects.id INNER JOIN
dbo.systypes ON dbo.syscolumns.xtype = dbo.systypes.xtype
WHERE
(dbo.sysobjects.name = @objName)
AND
(dbo.systypes.status <> 1)
ORDER BY
dbo.sysobjects.name,
dbo.syscolumns.colorder
SET @parameterCount=(SELECT count(*) FROM #t_obj)
IF(@parameterCount<1) SET @errMsg='No Parameters/Fields found for ' + @objName
IF(@errMsg is null)
BEGIN
PRINT 'try'
PRINT ' {'
PRINT ' SqlParameter[] paramsToStore =
new SqlParameter[' + cast(@parameterCount as varchar) + '];'
PRINT ''
DECLARE @source_name nvarchar,@source_type varchar,
@col_name nvarchar(100),@col_order int,@col_type varchar(20),
@col_len int,@col_key int,@col_xtype int,@col_redef varchar(20)
DECLARE cur CURSOR FOR
SELECT * FROM #t_obj
OPEN cur
FETCH NEXT FROM cur
INTO @source_name,@source_type,@col_name,@col_order,
@col_len,@col_key,@col_xtype
if(@source_type=N'U') SET @parameterAt='@'
WHILE @@FETCH_STATUS = 0
BEGIN
SET @col_redef=(SELECT
CASE @col_xtype
WHEN 34 THEN 'Image'
WHEN 35 THEN 'Text'
WHEN 48 THEN 'TinyInt'
WHEN 52 THEN 'SmallInt'
WHEN 56 THEN 'Int'
WHEN 58 THEN 'SmallDateTime'
WHEN 59 THEN 'Real'
WHEN 60 THEN 'Money'
WHEN 61 THEN 'DateTime'
WHEN 62 THEN 'Float'
WHEN 99 THEN 'NText'
WHEN 104 THEN 'Bit'
WHEN 106 THEN 'Decimal'
WHEN 122 THEN 'SmallMoney'
WHEN 127 THEN 'BigInt'
WHEN 165 THEN 'VarBinary'
WHEN 167 THEN 'VarChar'
WHEN 173 THEN 'Binary'
WHEN 175 THEN 'Char'
WHEN 231 THEN 'NVarChar'
WHEN 239 THEN 'NChar'
ELSE '!MISSING'
END AS C)
PRINT ' paramsToStore[' + cast(@col_order-1 as varchar)
+ '] = new SqlParameter("' + @parameterAt + @col_name
+ '", SqlDbType.' + @col_redef
+ ');'
IF(@col_xtype=231)OR(@col_xtype=167)OR(@col_xtype=175)
OR(@col_xtype=99)OR(@col_xtype=35)
BEGIN
PRINT ' paramsToStore[' + cast(@col_order-1 as varchar)
+ '].Size=' + cast(@col_len as varchar) + ';'
END
PRINT ' paramsToStore['+ cast(@col_order-1 as varchar)
+ '].Value = ;'
FETCH NEXT FROM cur
INTO @source_name,@source_type,@col_name,@col_order,
@col_len,@col_key,@col_xtype
END
PRINT ''
PRINT ' SqlHelper.ExecuteNonQuery(' + @connName +
', CommandType.StoredProcedure,"' + @objName + '", paramsToStore);'
PRINT ' }'
PRINT 'catch(Exception excp)'
PRINT ' {'
PRINT ' }'
PRINT 'finally'
PRINT ' {'
PRINT ' ' + @connName + '.Dispose();'
PRINT ' ' + @connName + '.Close();'
PRINT ' }'
CLOSE cur
DEALLOCATE cur
END
if(LEN(@errMsg)>0) PRINT @errMsg
DROP TABLE #t_obj
SET NOCOUNT ON
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
Output Exampletry
{
SqlParameter[] paramsToStore = new SqlParameter[9];
paramsToStore[0] = new SqlParameter("@organisationid", SqlDbType.BigInt);
paramsToStore[0].Value = ;
paramsToStore[1] = new SqlParameter("@DisplayName", SqlDbType.NVarChar);
paramsToStore[1].Size=100;
paramsToStore[1].Value = ;
paramsToStore[2] = new SqlParameter("@DefaultCurrencyFID", SqlDbType.Int);
paramsToStore[2].Value = ;
paramsToStore[3] = new SqlParameter("@TaxCode", SqlDbType.NVarChar);
paramsToStore[3].Size=60;
paramsToStore[3].Value = ;
paramsToStore[4] = new SqlParameter("@UserFID", SqlDbType.BigInt);
paramsToStore[4].Value = ;
paramsToStore[5] = new SqlParameter("@IsClient", SqlDbType.Bit);
paramsToStore[5].Value = ;
paramsToStore[6] = new SqlParameter("@IsContractor", SqlDbType.Bit);
paramsToStore[6].Value = ;
paramsToStore[7] = new SqlParameter("@IsSupplier", SqlDbType.Bit);
paramsToStore[7].Value = ;
paramsToStore[8] = new SqlParameter("@IsDesigner", SqlDbType.Bit);
paramsToStore[8].Value = ;
SqlHelper.ExecuteNonQuery(conn.Connection,
CommandType.StoredProcedure,"usp_Insert_Organisation", paramsToStore);
}
catch(Exception excp)
{
}
finally
{
conn.Connection.Dispose();
conn.Connection.Close();
}
All you then have to do is copy-paste and fill in the values you want to pass and catch any exceptions... (Yes you do have to write some code!).
Points of Interest
In order for me to work out the @col_xtype variable from sysobjects, I ran lots of tests on a table I created with every type variation in both directions. It certainly works fine for all the usual data types, but I haven't had a chance to test all types within .NET, so if you find a bug, let me know. Enjoy!
History
- Feb 20, 2006 - updated the script to version 1.1 which includeds two additions:
UniqueIdentifier data type support.
- Support for
ParameterDirection.Output.
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 41 (Total in Forum: 41) (Refresh) | FirstPrevNext |
|
|
 |
|
|
 |
|
|
 |
|
|
I took the liberty of adding a couple of things to the script to fit some of my projects. Here's what I added:
a) Updated to include 'Scale' for 'Numeric' and 'Decimal'. b) Updated to include 'Precision' for 'Numeric' and 'Decimal'. c) Added the column type (@col_xtype) for types that are "missing" from the definition for further debugging.
Also changed the name of the proc - sorry Paul
Enjoy!!!
CREATE PROCEDURE [dbo].[tools_STOREDPROC_Builder] ( @objName nvarchar(100) ) AS /* ___________________________________________________________________ Name: CS SPROC Builder Version: 1 Date: 10/09/2004 Author: Paul McKenzie Description: Call this stored procedue passing the name of your database object that you wish to insert/update from .NET (C#) and the code returns code to copy and paste into your application. This version is for use with "Microsoft Data Application Block". Version: 1.1 Date: 17/02/2006 Author: Paul McKenzie Description: a) Updated to include 'UniqueIdentifier' Data Type b) Support for 'ParameterDirection.Output'
Version: 1.2 Date: 29/08/2007 Author: Rob Richard Description: a) Updated to include 'Scale' for 'Numeric' and 'Decimal' b) Updated to include 'Precision' for 'Numeric' and 'Decimal' c) Added the column type (@col_xtype) for types that are "missing" from the definition for further debugging
*/ SET NOCOUNT ON DECLARE @parameterCount int DECLARE @errMsg varchar(100) DECLARE @parameterAt varchar(1) DECLARE @connName varchar(100) DECLARE @outputValues varchar(100) --Change the following variable to the name of your connection instance SET @connName='conn.Connection' SET @parameterAt='' SET @outputValues='' SELECT dbo.sysobjects.name AS ObjName, dbo.sysobjects.xtype AS ObjType, dbo.syscolumns.name AS ColName, dbo.syscolumns.colorder AS ColOrder, dbo.syscolumns.length AS ColLen, dbo.syscolumns.colstat AS ColKey, dbo.syscolumns.prec AS ColPrecision, dbo.syscolumns.scale AS ColScale, dbo.syscolumns.isoutparam AS ColIsOut, dbo.systypes.xtype INTO #t_obj FROM dbo.syscolumns INNER JOIN dbo.sysobjects ON dbo.syscolumns.id = dbo.sysobjects.id INNER JOIN dbo.systypes ON dbo.syscolumns.xtype = dbo.systypes.xtype WHERE (dbo.sysobjects.name = @objName) AND (dbo.systypes.status <> 1) ORDER BY dbo.sysobjects.name, dbo.syscolumns.colorder
SET @parameterCount=(SELECT count(*) FROM #t_obj) IF(@parameterCount<1) SET @errMsg='No Parameters/Fields found for ' + @objName IF(@errMsg is null) BEGIN PRINT 'try' PRINT ' {' PRINT ' SqlParameter[] spParams = new SqlParameter[' + cast(@parameterCount as varchar) + '];' PRINT '' DECLARE @source_name nvarchar,@source_type varchar, @col_name nvarchar(100),@col_order int,@col_type varchar(20), @col_len int,@col_key int,@col_xtype int,@col_redef varchar(20), @col_precision int, @col_scale int, @col_isout tinyint DECLARE cur CURSOR FOR SELECT * FROM #t_obj OPEN cur -- Perform the first fetch. FETCH NEXT FROM cur INTO @source_name,@source_type,@col_name,@col_order,@col_len,@col_key,@col_precision,@col_scale,@col_isout,@col_xtype if(@source_type=N'U') SET @parameterAt='@' -- Check @@FETCH_STATUS to see if there are any more rows to fetch. WHILE @@FETCH_STATUS = 0 BEGIN SET @col_redef=(SELECT CASE @col_xtype WHEN 34 THEN 'Image' WHEN 35 THEN 'Text' WHEN 36 THEN 'UniqueIdentifier' WHEN 48 THEN 'TinyInt' WHEN 52 THEN 'SmallInt' WHEN 56 THEN 'Int' WHEN 58 THEN 'SmallDateTime' WHEN 59 THEN 'Real' WHEN 60 THEN 'Money' WHEN 61 THEN 'DateTime' WHEN 62 THEN 'Float' WHEN 99 THEN 'NText' WHEN 104 THEN 'Bit' WHEN 106 THEN 'Decimal' WHEN 108 THEN 'Numeric' WHEN 122 THEN 'SmallMoney' WHEN 127 THEN 'BigInt' WHEN 165 THEN 'VarBinary' WHEN 167 THEN 'VarChar' WHEN 173 THEN 'Binary' WHEN 175 THEN 'Char' WHEN 231 THEN 'NVarChar' WHEN 239 THEN 'NChar' ELSE '!MISSING ' + CAST(@col_xtype AS varchar(20)) END AS C)
--Write out the parameter PRINT ' spParams[' + cast(@col_order-1 as varchar) + '] = new SqlParameter("' + @parameterAt + @col_name + '", SqlDbType.' + @col_redef + ');'
--Write out the parameter direction it is output IF(@col_isout=1) BEGIN PRINT ' spParams['+ cast(@col_order-1 as varchar) +'].Direction=ParameterDirection.Output;' SET @outputValues=@outputValues+' ?=spParams['+ cast(@col_order-1 as varchar) +'].Value;' END ELSE BEGIN --Write out the parameter value line PRINT ' spParams['+ cast(@col_order-1 as varchar) + '].Value = ?;' END --If the type is a string then output the size declaration IF(@col_xtype=231)OR(@col_xtype=167)OR(@col_xtype=175)OR(@col_xtype=99)OR(@col_xtype=35) BEGIN PRINT ' spParams[' + cast(@col_order-1 as varchar) + '].Size=' + cast(@col_len as varchar) + ';' END --If the type is a funky number then output the scale and precision declarations IF(@col_xtype=108)OR(@col_xtype=106) BEGIN PRINT ' spParams[' + cast(@col_order-1 as varchar) + '].Precision=' + cast(@col_precision as varchar) + ';' PRINT ' spParams[' + cast(@col_order-1 as varchar) + '].Scale=' + cast(@col_scale as varchar) + ';' END
-- This is executed as long as the previous fetch succeeds. FETCH NEXT FROM cur INTO @source_name,@source_type,@col_name,@col_order, @col_len,@col_key,@col_precision,@col_scale,@col_isout,@col_xtype END PRINT '' PRINT ' SqlHelper.ExecuteNonQuery(' + @connName + ', CommandType.StoredProcedure,"' + @objName + '", spParams);' PRINT @outputValues PRINT ' }' PRINT 'catch(Exception excp)' PRINT ' {' PRINT ' }' PRINT 'finally' PRINT ' {' PRINT ' ' + @connName + '.Dispose();' PRINT ' ' + @connName + '.Close();' PRINT ' }' CLOSE cur DEALLOCATE cur END if(LEN(@errMsg)>0) PRINT @errMsg DROP TABLE #t_obj SET NOCOUNT ON
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
Because of programmers like you, others are inspired to become better at coding. Who needs something like CodeSmith. This is a brilliant piece of coding. Bravo! Well done!
|
| Sign In·View Thread·PermaLink | 3.50/5 (2 votes) |
|
|
|
 |
|
|
Very handy tool thanks a lot.
If you get a chance have a look at GENNIT @ http://gennit.com it is a code generator tool which uses industrial strength foundations (NHibernate / ActiveRecord) to build a DAL from scratch (as well as other generators such as XHTML and Facebook API), all using online tools - you download a zip file containing the VS project with everything you designed, ready to go.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
i am working on how to calucate Interest in Saving account using Visual studio and SQl Server Express Edtion.
i have a AmountIn, AmountOut and Balance Field... in SavingAccountTable
net interest will be automatically added every month......Help coz i don't know how to go on about this
thanks
Please anybody help
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
This is a good way. However, consider a professional web project, you may want to use SqlHelperParameterCache from Microsoft instead.
SqlHelperParameterCache has overhead if your project only calls most stored procedures once in a life time. Of course that's not the real case because most web projects are not to be used for only 1 visit then scrap the website.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hello,
I've written a custom generator which generates Stored Procs as well as DAL code. pretty funky. Feel free to check it out =) please let me know what you think. 
http://www.codeauthor.org[^]
Xin Zhao http://www.codeauthor.org
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
How about a SQL stored procedure generator and c# DAL generator for almost nothing! Then check out my www.dashSQL.com. dashSQL generaters all the code for stored procedures and as well as a base data access layer and then another c# DAL class that gets created per your table. No need for parameter types, int, varchar, etc. All parameters in the dashSQL code generator are strings!! SQL automatically converts everything for you! Give it a try! www.dashsql.com
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
My issue with SubSonic, nHibernate and CodeAuthor is tha fact that they use adhoc or parameterized queries.
Using Stored Procedures is more secure than using adhoc queries or even parameterized queries via the command builder.
The security problem that this creates is that you are forced to assign SELECT permissions for tables, to the account that is running the queries.
What you really want is to assign EXEC permissions against your stored procedures. That way, users only get access to the data you package for them, not access to the entire table.
Here's a c# generator that also uses stored procedures exclusively:
OxyGen Code
http://www.techinceptions.com/codegenerator.html
You get pure commented c# code, paging (data source paging), caching etc.
And no dlls (but you can choose an option to compile the output).
The data is presented as generic lists or class instances, and there's special handling for static tables as well.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
This is really sweet but has anyone used this with an output variable set by ScopeIdentity? If so could someone please post an example of how to do this.
Thanks.!
Chaci Mulch
|
| Sign In·View Thread·PermaLink | 2.00/5 (2 votes) |
|
|
|
 |
|
|
Here's what would be ideal for me:
A Visual Studio add-in that would allow you to generate C# calling code for a sproc simply by right-clicking the sproc in the server explorer and selecting "generate C# method". It would then analyze the sproc and generate a corresponding C# static class with methods to execute the sproc, get the SqlParameter[] for the sproc, overloads to execute the sproc with a specified connection, transaction, etc...
For example, say we have
ALTER PROC AddNewSignature (@Description varchar(255), @UserID uniqueidentifier, @Signature text, @EmailAccountID uniqueidentifier = null) as
DECLARE @GUID uniqueidentifier SELECT @GUID = newid() INSERT SignatureTable (ID,Description,UserID,Signature) SELECT @GUID,@Description, @UserID, @Signature exec AssociateSignatureToMailAccount @SignatureID = @GUID, @MailAccID = @EmailAccountID END
I want it to generate a C# static class containing methods like
public static void AddNewSignature(string description, Guid userID, string signature, Guid emailAccountID) { // create Sql parameters, command, and connection here, then execute. }
The method would have overloads for supplying connection, transactions, etc. Additionally, there would be more methods in the class that would just generate the SqlCommand with parameters and connection, allowing the consumer code to actually perform the execution. This would be important as many data tiers have custom execution with custom error handling.
Tech, life, family, faith: Give me a visit. I'm currently blogging about: Connor's Christmas Spectacular! Judah Himango
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
CREATE PROCEDURE tools_CS_SPROC_Builder_2005 ( @objName nvarchar(100), @Executetype nvarchar(100) -- ExecuteNonQuery -or- ExecuteReader -or- ExecuteScalar ) AS /* ___________________________________________________________________ Name: CS SPROC Builder Version: 1 Date: 10/09/2004 Author: Paul McKenzie Description: Call this stored procedue passing the name of your database object that you wish to insert/update from .NET (C#) and the code returns code to copy and paste into your application. This version is for use with "Microsoft Data Application Block". Version: 1.1 Date: 17/02/2006 Author: Paul McKenzie Description: a) Updated to include 'UniqueIdentifier' Data Type b) Support for 'ParameterDirection.Output'
*/ SET NOCOUNT ON DECLARE @parameterCount int DECLARE @errMsg varchar(100) DECLARE @parameterAt varchar(1) DECLARE @connName varchar(100) DECLARE @outputValues varchar(100) --Change the following variable to the name of your connection instance SET @connName='ConfigurationSettings.AppSettings("connectionString")' SET @parameterAt='' SET @outputValues='' SELECT dbo.sysobjects.name AS ObjName, dbo.sysobjects.xtype AS ObjType, REPLACE(dbo.syscolumns.name,'@','') AS ColName, dbo.syscolumns.colorder AS ColOrder, dbo.syscolumns.length AS ColLen, dbo.syscolumns.colstat AS ColKey, dbo.syscolumns.isoutparam AS ColIsOut, dbo.systypes.xtype INTO #t_obj FROM dbo.syscolumns INNER JOIN dbo.sysobjects ON dbo.syscolumns.id = dbo.sysobjects.id INNER JOIN dbo.systypes ON dbo.syscolumns.xtype = dbo.systypes.xtype WHERE (dbo.sysobjects.name = @objName) AND (dbo.systypes.status <> 1) ORDER BY dbo.sysobjects.name, dbo.syscolumns.colorder
SET @parameterCount=(SELECT count(*) FROM #t_obj) IF(@parameterCount<1) SET @errMsg='No Parameters/Fields found for ' + @objName IF(@errMsg is null) BEGIN
DECLARE @source_name nvarchar,@source_type varchar, @col_name nvarchar(100),@col_order int,@col_type varchar(20), @col_len int,@col_key int,@col_xtype int,@col_redef varchar(20), @col_isout tinyint
IF @ExecuteType = 'ExecuteNonQuery' BEGIN PRINT 'SUB '+@objName+'( _' END IF @ExecuteType = 'ExecuteReader' BEGIN PRINT 'FUNCTION '+@objName+'( _' END IF @ExecuteType = 'ExecuteScalar' BEGIN PRINT 'FUNCTION '+@objName+'( _' END
declare @parameterOut nvarchar(1000)
DECLARE cur CURSOR FOR SELECT * FROM #t_obj OPEN cur -- Perform the first fetch. FETCH NEXT FROM cur INTO @source_name,@source_type,@col_name,@col_order,@col_len,@col_key,@col_isout,@col_xtype --if(@source_type=N'U') SET @parameterAt='' -- Check @@FETCH_STATUS to see if there are any more rows to fetch. WHILE @@FETCH_STATUS = 0 BEGIN SET @col_redef=(SELECT CASE @col_xtype WHEN 34 THEN 'Binary' WHEN 35 THEN 'String' WHEN 36 THEN 'Guid' WHEN 48 THEN 'Byte' WHEN 52 THEN 'Int16' WHEN 56 THEN 'Int32' WHEN 58 THEN 'DateTime' WHEN 59 THEN 'Single' WHEN 60 THEN 'Currency' WHEN 61 THEN 'DateTime' WHEN 62 THEN 'Double' WHEN 99 THEN 'String' WHEN 104 THEN 'Boolean' WHEN 106 THEN 'Decimal' WHEN 122 THEN 'Currency' WHEN 127 THEN 'Int64' WHEN 165 THEN 'Binary' WHEN 167 THEN 'String' WHEN 173 THEN 'Binary' WHEN 175 THEN 'String' WHEN 231 THEN 'String' WHEN 239 THEN 'String' ELSE '!MISSING' END AS C)
--capture parameter select @parameterOut = ' ByVal ' + @col_name+ ' AS '+@col_redef
-- This is executed as long as the previous fetch succeeds. FETCH NEXT FROM cur INTO @source_name,@source_type,@col_name,@col_order, @col_len,@col_key,@col_isout,@col_xtype
IF @@FETCH_STATUS<>0 BEGIN PRINT @parameterOut + ' _' END IF @@FETCH_STATUS=0 BEGIN PRINT @parameterOut+', _' END END CLOSE cur DEALLOCATE cur
IF @ExecuteType = 'ExecuteNonQuery' BEGIN PRINT ')' END IF @ExecuteType = 'ExecuteReader' BEGIN PRINT ') AS SQLDATAREADER' END IF @ExecuteType = 'ExecuteScalar' BEGIN PRINT ') AS ?' END
PRINT '' PRINT ' Dim db As Database = DatabaseFactory.CreateDatabase() ' PRINT ' Dim sqlCommand As String = "'+@objName+'" ' PRINT ' Dim dbCommand As DbCommand = db.GetStoredProcCommand(sqlCommand) ' PRINT '' DE | | | | | |