473,382 Members | 1,404 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

Execute Big Dynamic SQL in Stored Procedure to Create View

MD
I am trying to create a dynamic SQL statement to create a view.
I have a stored procedure, which based on the parameters passed calls
different stored procedures. Each of this sub stored procedure creates
a string of custom SQL statement and returns this string back to the
main stored procedure.

This SQL statements work fine on there own. The SQL returned from the
sub stored procedure are returned fine. The datatype of the variable
that this sql is stored in Varchar(I have tried using nvarchar also
same problem).

If I have more that 6 SQL statements concated then the main SQL gets
cut off. It doesnt matter in what sequence I create the main SQL.

Here is the Stored procedure

/**********************************************/
/*Main Stored Procedure */

/**********************************************/
CREATE PROC sp_generate_invoice1 @prev_date NVarchar(1000) ,
@prev_month NVarchar(32)
AS

DECLARE invoice_driver_cur CURSOR FOR
Select driversid From Invoice_drivers

Open invoice_driver_cur
Declare
@C VARCHAR(8000),
@L_args Varchar(8000),
@@sqlstmt Varchar(8000),
@L_driverid Int,
@L_rowcount Int

SET QUOTED_IDENTIFIER ON

SET TEXTSIZE 32768
Set @L_rowcount = 0

-- Drop the previous View
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
WHERE TABLE_NAME = 'custom_invoice')
DROP VIEW custom_invoice

Fetch Next From invoice_driver_cur
Into @L_driverid

-- Create the new View
Set @L_args = N'Create View custom_invoice As'

--Select @L_driverid

WHILE ( @@FETCH_STATUS = 0)
BEGIN
Set @L_rowcount = @L_rowcount + 1
select @L_driverid
If @L_driverid = 2
Begin
Exec sp_invoice_driver2 @prev_date, @prev_month, @@sqlstmt Output

If @L_rowcount > 1
Begin
Set @C = @L_args + ' Union ' + @@sqlstmt
End
Else
Begin
Set @C = @L_args + @@sqlstmt
End
End

If @L_driverid = 3
Begin
Exec sp_invoice_driver3 @prev_date, @prev_month, @@sqlstmt Output

If @L_rowcount > 1
Begin
Set @C = @C + ' Union ' + @@sqlstmt
End
Else
Begin
Set @C = @L_args + @@sqlstmt
End
End

If @L_driverid = 4
Begin
Exec sp_invoice_driver4 @prev_date, @prev_month, @@sqlstmt Output

If @L_rowcount > 1
Begin
Set @C = @C + ' Union ' + @@sqlstmt
End
Else
Begin
Set @C = @L_args + @@sqlstmt
End
End

If @L_driverid = 5
Begin
Exec sp_invoice_driver5 @prev_date, @prev_month, @@sqlstmt Output

If @L_rowcount > 1
Begin
Set @C = @C + ' Union ' + @@sqlstmt
End
Else
Begin
Set @C = @L_args + @@sqlstmt
End
End

If @L_driverid = 6
Begin
Exec sp_invoice_driver6 @prev_date, @prev_month, @@sqlstmt Output

If @L_rowcount > 1
Begin
Set @C = @C + ' Union ' + @@sqlstmt
End
Else
Begin
Set @C = @L_args + @@sqlstmt
End
End

If @L_driverid = 7
Begin
Exec sp_invoice_driver7 @prev_date, @prev_month, @@sqlstmt Output

If @L_rowcount > 1
Begin
Set @C = @C + ' Union ' + @@sqlstmt
End
Else
Begin
Set @C = @L_args + @@sqlstmt
End
End

If @L_driverid = 8
Begin
Exec sp_invoice_driver8 @prev_date, @prev_month, @@sqlstmt Output

If @L_rowcount > 1
Begin
Set @C = @C + ' Union ' + @@sqlstmt
End
Else
Begin
Set @C = @L_args + @@sqlstmt
End
End

If @L_driverid = 10
Begin
Exec sp_invoice_driver_niku @prev_date, @prev_month, @L_driverid,
@@sqlstmt Output

If @L_rowcount > 1
Begin
Set @C = @C + ' Union ' + @@sqlstmt
End
Else
Begin
Set @C = @L_args + @@sqlstmt
End
End
Print @C
Fetch Next From invoice_driver_cur
Into @L_driverid

Continue

End
Close invoice_driver_cur
DeAllocate invoice_driver_cur

Exec (@C)
--EXEC sp_executesql @C
GO
/**********************************************/

/*Sub Procedure sp_invoice_driver2 */

/**********************************************/

CREATE PROC sp_invoice_driver2 @args NVarchar(1000), @prev_month
NVarchar(100),
@sqlstmt Varchar(8000) Output
AS

SET QUOTED_IDENTIFIER ON

SET @sqlstmt = ' Select 1 SortOrder ,
( SELECT Drivers.Description) Description,
(BillingReport.Active_Accounts * Cast(Fee.fee_rate As decimal(4,2)
)) / 12 Amount,
Drivers.Currency
FROM BillingReport, Drivers, Fee
WHERE ( Fee.Driverid = Drivers.Driversid ) and
Drivers.Driversid = 2 and
billingreport.fromdate = ''' + Cast(@args As NVARCHAR(20)) + '''
and
fee.currentmonth = ''' + Cast(@prev_month As NVARCHAR(12)) +' '''

GO

/**********************************************/

This is what the Print Statement give:

/**********************************************/
Create View custom_invoice As Select 1 SortOrder ,
( SELECT Drivers.Description) Description,
(BillingReport.Active_Accounts * Cast(Fee.fee_rate As decimal(4,2)
)) / 12 Amount,
Drivers.Currency
FROM BillingReport, Drivers, Fee
WHERE ( Fee.Driverid = Drivers.Driversid ) and
Drivers.Driversid = 2 and
billingreport.fromdate = '9/1/2004' and
fee.currentmonth = 'September ' Union Select 2,
(SELECT Drivers.Description),
(BillingReport.Zero_Balance * Cast(Fee.fee_rate As decimal(9,2) ))
/ 12 Amount,
Drivers.Currency
FROM BillingReport, Drivers, Fee
WHERE ( Fee.Driverid = Drivers.Driversid ) and
billingreport.fromdate = '9/1/2004' and
fee.currentmonth = 'September' and
Drivers.Driversid = 3 Union Select 3,
(Select Drivers.Description From Drivers Where DriversID = 4),
Count(*) * Cast((select fee.fee_rate
from fee, drivers
where Fee.Driverid = Drivers.Driversid and
fee.currentmonth = 'September' and
Drivers.Driversid = 4 )As decimal(6,2)) / 12,
(Select Drivers.Currency
From Drivers Where DriversID = 4)
From Fund Union Select 4,
(Select Drivers.Description From Drivers Where DriversID = 5),
(((Sum(BillingReport.Man_Reg_Purch + BillingReport.Man_Reg_Red +
BillingReport.Man_Reg_Transexch +
BillingReport.Man_Allo_Purch +
BillingReport.Man_Allo_Red +
BillingReport.Man_Allo_Transexch +
BillingReport.Man_Allo_Adj_Purch +
BillingReport.Man_Allo_Adj_Red +
BillingReport.Man_Allo_Adj_Transexch +
BillingReport.Man_Adj_Purch +
BillingReport.Man_Adj_Red +
BillingReport.Man_Adj_Transexch ) ) +
(Select Sum(Cast(satuscnt As int ))
From Awd_stub
Where CurrentMonth = 'September'))) *
(Cast((select fee.fee_rate
from fee, drivers
where Fee.Driverid = Drivers.Driversid and
fee.currentmonth = 'September' and
Drivers.Driversid = 5 )As decimal(6,2))),
(Select Drivers.Currency From Drivers Where DriversID = 5)
FROM BillingReport
Where billingreport.fromdate = '9/1/2004' Union Select 5,
(Select Drivers.Description From Drivers Where DriversID = 6),
( Sum( BillingReport.Auto_Reg_Purch +
BillingReport.Auto_Reg_Red +
BillingReport.Auto_Reg_TRansexch +
BillingReport.Auto_Allo_Purch+
BillingReport.Auto_Allo_Red +
BillingReport.Auto_Allo_Transexch+
BillingReport.Auto_Allo_Adj_Purch+
BillingReport.Auto_Allo_Adj_Red+
BillingReport.Auto_Allo_Adj_transexch+
BillingReport.Auto_Adj_Purch+
BillingReport.Auto_Adj_Red+
BillingReport.Auto_Adj_Transexch )+
(Select Sum(Cast(Processed_msg As Int))
From XML_messaging
Where CurrentMonth = 'September'))*
(Cast((select fee.fee_rate
from fee, drivers
where Fee.Driverid = Drivers.Driversid and
fee.currentmonth = 'September' and
Drivers.Driversid = 6 )As decimal(6,2))),
(Select Drivers.Currency From Drivers Where DriversID = 6)
FROM BillingReport
Where billingreport.fromdate = '9/1/2004' Union Select 6,
(Select Drivers.Description From Drivers Where DriversID = 7),
( ( a.Accountholder_Active_Accounts -
( select accountholder_active_accounts from billingreport where
Month(fromdate) = Month('9/1/2004')-1 ) )
+
( a.Accountholder_Zero_Balance -
( select accountholder_zero_balance from billingreport where
Month(fromdate) = Month('9/1/2004')-1 ))) *
(Cast((select fee.fee_rate
from fee, drivers
where Fee.Driverid = Drivers.Driversid and
fee.currentmonth = 'September' and
Drivers.Driversid = 7 )As decimal(6,2))),
(Select Drivers.Currency From Drivers Where DriversID = 7)
FROM BillingReport a Where a.fromdate = '9/1/2004' Union Select 7,
(Select Drivers.Description From Drivers Where DriversID = 8),
( Select telephone From cfxbill Where currentmonth = 'September') *
(Cast((select fe

Thanks for any help
MD
Jul 20 '05 #1
4 8026
This is the worst use of SQL I have ever seen in 18 years of
programming in the language. If I put this in my next book, nobody
would believe it was real.
I am trying to create a dynamic SQL statement to create a view. <<
Which completely defeats the purpose of a VIEW and does it by using
the worst possible approach for production code. Dynamic SQL says that
you have no idea what your own schema should look like, so you assume
that any random user sometime in the future is going to do a better
job.
I have a stored procedure, which based on the parameters passed calls different stored procedures. Each of this sub stored procedure
creates a string of custom SQL statement and returns this string back
to the main stored procedure. <<

Ever have a course in Software Engineering? Obviously not. I cannot
take the time to go over all the probldms with this approach; just get
a book on SE and read it. This has nothing to do with SQL per se, but
with the very **basics** of your trade.

I tried for almost an hour to just read and understand your code. How
do you expect anyone to maintain it? Your inconsistent
capitalization, failure to use alias table names and use of tabs in
the code was also a pain to the reader.
If I have more that 6 SQL statements concated then the main SQL

gets cut off. It doesn't matter in what sequence I create the main
SQL. <<

You are probably generating so much crappy code that you are
overflowing the limits of SQL Server.

Did you know that T-SQL was never meant to be an application
development language? As best I can figure out, this nightmare is a
UNION-ed mess of unrelated reports. Break it apart into VIEWs --
**real** VIEWs that are part of the schema, and not this
conglomeration of confused reports. Get rid of the hard-wired date;
if you want to write a stored procedure, you can make it a parameter.
Get rid of the string month name; in a tiered architecture, display is
done in the front end, not the database (again, that has nothign to do
with SQL per se, but is just a basic progrmaming principle).

Try things more like this:

CREATE VIEW Driver_2_invoice (description, from_date, amount,
currency)
AS
SELECT D1.description,
B1.from_date,
(B1.active_accounts * F1.fee_rate)/12.00,
D1.currency
FROM BillingReports AS B1, Drivers AS D1, Fee AS F1
WHERE F1.driver_id = 2
AND D1.driver_id = 2;

But did you notice that "BillingReports" is CROSS JOIN-ed? When you
use the VIEW, you apply a from_date to it to get the range you want.

and so on for the other UNION-ed queries.

CREATE VIEW Driver_3_invoice (description, from_date, amount,
currency)
AS
SELECT D1.description, B1.from_date,
B1.zero_balance * F1.fee_rate) / 12.00,
D1.currency
FROM BillingReport AS B1, Drivers AS D1, Fee AS F1
WHERE F1.driver_id = 3
AND D1.driver_id = 3;

Etc.

If this is how you are writing queries, it is a pretty good bet that
the DDL is also a nightmare of bad datatypes, lack of constraints and
so forth.
Jul 20 '05 #2
MD
jc*******@earthlink.net (--CELKO--) wrote in message news:<18**************************@posting.google. com>...
This is the worst use of SQL I have ever seen in 18 years of
programming in the language. If I put this in my next book, nobody
would believe it was real.
I am trying to create a dynamic SQL statement to create a view. <<
Which completely defeats the purpose of a VIEW and does it by using
the worst possible approach for production code. Dynamic SQL says that
you have no idea what your own schema should look like, so you assume
that any random user sometime in the future is going to do a better
job.
I have a stored procedure, which based on the parameters passed calls different stored procedures. Each of this sub stored procedure
creates a string of custom SQL statement and returns this string back
to the main stored procedure. <<

Ever have a course in Software Engineering? Obviously not. I cannot
take the time to go over all the probldms with this approach; just get
a book on SE and read it. This has nothing to do with SQL per se, but
with the very **basics** of your trade.

I tried for almost an hour to just read and understand your code. How
do you expect anyone to maintain it? Your inconsistent
capitalization, failure to use alias table names and use of tabs in
the code was also a pain to the reader.
If I have more that 6 SQL statements concated then the main SQL

gets cut off. It doesn't matter in what sequence I create the main
SQL. <<

You are probably generating so much crappy code that you are
overflowing the limits of SQL Server.

Did you know that T-SQL was never meant to be an application
development language? As best I can figure out, this nightmare is a
UNION-ed mess of unrelated reports. Break it apart into VIEWs --
**real** VIEWs that are part of the schema, and not this
conglomeration of confused reports. Get rid of the hard-wired date;
if you want to write a stored procedure, you can make it a parameter.
Get rid of the string month name; in a tiered architecture, display is
done in the front end, not the database (again, that has nothign to do
with SQL per se, but is just a basic progrmaming principle).

Try things more like this:

CREATE VIEW Driver_2_invoice (description, from_date, amount,
currency)
AS
SELECT D1.description,
B1.from_date,
(B1.active_accounts * F1.fee_rate)/12.00,
D1.currency
FROM BillingReports AS B1, Drivers AS D1, Fee AS F1
WHERE F1.driver_id = 2
AND D1.driver_id = 2;

But did you notice that "BillingReports" is CROSS JOIN-ed? When you
use the VIEW, you apply a from_date to it to get the range you want.

and so on for the other UNION-ed queries.

CREATE VIEW Driver_3_invoice (description, from_date, amount,
currency)
AS
SELECT D1.description, B1.from_date,
B1.zero_balance * F1.fee_rate) / 12.00,
D1.currency
FROM BillingReport AS B1, Drivers AS D1, Fee AS F1
WHERE F1.driver_id = 3
AND D1.driver_id = 3;

Etc.

If this is how you are writing queries, it is a pretty good bet that
the DDL is also a nightmare of bad datatypes, lack of constraints and
so forth.

Thank you for your comments. I will get a book on SE and follow some
of your pointer. I understand that you have written a numerous books
on SQL but surely there is not need to be rude! I have overlooked the
alias part but without even knowing what my user requirements are try
not to pass judgement. Again thank you for your feed back considering
that you had to waste 1 hr going through my code. For sure I am going
to buy one of your books, which one would you recommend?
Jul 20 '05 #3
>> I will get a book on SE and follow some
of your pointer. <<

The classics are by Yourdon, DeMacro and Constantine. I also like Gane
& Sarson for systems level stuff -- IST is a better diagramming method
than Yourdon.
I understand that you have written a numerous books on SQL but surely there is not need to be rude! <<

My wife is the fukatan at a Zen monastary; they beat their students with
sticks :)
For sure I am going to buy one of your books, which one would you

recommend? <<

SQL FOR SMARTIES is the classic that most SQL programmer have on their
desk with post-it notes sticking out of it. It is a collection of SQL
programming techniques. I will start work on the third edition next
month, but I have no idea when it will come out; certainly not until
2005.

my DATA & DATABASES is a good look at foundations and some hueristics
for database in general. Pay attention to scales and measurements and
the design of encoding schemes; I seem to be the only guy who talks
about how to actually design data representations as opposed to
databases.

Terry Halpin's ORM book is great for data modeling.

if you want a mental workout to see if you are getting the idea of
thinking in sets, I also have a SQL PUZZLES & ANSWERS book. Sales were
lousy, but teachers keep using it for homework assignments.

--CELKO--
Please post DDL, so that people do not have to guess what the keys,
constraints, Declarative Referential Integrity, datatypes, etc. in your
schema are. Sample data is also a good idea, along with clear
specifications.
*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Jul 20 '05 #4
[posted and mailed, please reply in news]

MD (md********@ifdsgroup.com) writes:
I am trying to create a dynamic SQL statement to create a view.
I have a stored procedure, which based on the parameters passed calls
different stored procedures. Each of this sub stored procedure creates
a string of custom SQL statement and returns this string back to the
main stored procedure.

This SQL statements work fine on there own. The SQL returned from the
sub stored procedure are returned fine. The datatype of the variable
that this sql is stored in Varchar(I have tried using nvarchar also
same problem).

If I have more that 6 SQL statements concated then the main SQL gets
cut off. It doesnt matter in what sequence I create the main SQL.


Supposedly the SQL statement by then exceeds 8000 characters.

The usual remedy is to have more than one SQL variable:

EXEC(@sql1 + @sql2 + @sql3 + ...)

But since you are in a loop, this is not possible. In the next version of
SQL Server, currently in Beta, there is a simple solution: use the new
varchar(MAX) datatype. Here you can fit in 2GB of SQL. Alas, in SQL 2000
you only have the text data type which you cannot assign to.

But there is a solution: insert all the SQL Segments into a temp table:

CREATE TABLE #sql(id int IDENTITY, sql varchar(8000) NOT NULL)

Now loop over this table and for each row append to two variables:

SELECT @a = '' -- Init
SELECT @b = 'EXEC('
...
SELECT @a = @a + 'DELCARE @sql' + ltrim(str(id)) + ' varchar(8000)
SELECT @sql = ' + sql,
@b = @b + '@sql' + ltrim(str(id)) + ' + '
FROM #sql
WHERE id = @id
...
-- Final
SELECT @b = @b + ''''')'

EXEC(@a + @b)

That is @a + @b builds a an batch that in its turn calls EXEC() to create
your view.

I hope that you by now realise that you have all reason to reconsider your
design.

--
Erland Sommarskog, SQL Server MVP, es****@sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Jul 20 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: John Wilson | last post by:
Hello, I have the following code which populates as table data from a SQL Server 2000 stored proc (RSByDemoID2). Below that is the view and stored procedure which takes @DemoID as input to match...
1
by: PJ | last post by:
<% Set Conn = Server.CreateObject("ADODB.Connection") Conn.open application("dtat_motor_connectionstring") set rs = new adodb.recordset 'Set RS = Conn.Execute(' "exec spcn_update_transactions &...
3
by: CSDunn | last post by:
Hello, I have a situation with MS Access 2000 in which I need to display report data in spreadsheet orientation (much like a datasheet view for a form). If you think of the report in terms of what...
1
by: Nathan Bloomfield | last post by:
Does anyone know if there is any documentation which relates to Access2k + ? or can anyone help adjust the code? I am having trouble converting the DAO references. TITLE :INF: How to...
2
by: Noloader | last post by:
Hello, Access XP, SQL Server 2000 Is it possible to hide a SP under Queries in Access, yet still be able to Execute it from Access? (Similar to hiding Tables, then using Views) We hooked...
4
by: Andrew | last post by:
Hey all, Been working with the Crystal Report Viewer, and have run into a situation I am hoping someone can help me get past. This may be more of a CR question, but hoping for some CR gurus to...
7
by: JIM.H. | last post by:
Hello, Is there any difference to between SLQ string in the code and call execute query and call a stored procedure and execute the query that way concerning speed, effectiveness, reliability,...
5
by: alingsjtu | last post by:
Hello, every body. When execute dynamic generated multiple OPENQUERY statements (which linkes to DB2) in SQLServer, I always got SQL1040N The maximum number of applications is already connected...
1
by: PVBHANU | last post by:
Hi, I am using DB2 V9.1 windows , can any one please tell me how to complile and execute a stored procedure. I followed Alldatabse->database->Application Object->stored procedure...But No...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.