Showing posts with label procedures. Show all posts
Showing posts with label procedures. Show all posts

Thursday, March 29, 2012

Backing up Stored procedures

Is there an easy simple way to backup all my personal Stored Procedures.

In the stored procedures collection, my stored procedures start with "DEF".

I would like to have the stored procedures places as text files in a personal backup folder.

Is this possible?

I have the query to get my SP's:

SELECT

*

FROM

SYSOBJECTS

WHERE

xtype='p'AND NameLIKE'DEF%'

ORDER

BY NAME

Next step is how to get the code inside each stored procedure to be exported to a .txt file.

How can I do this?

|||

You should do it at design time if possible.

You can try to send your stored procedure code as attachments in e-mail and next save this attachments or you can get stored procedure code using system stored procedure and save result to flat file output using SSIS package, You can also try to use Bulk copy?. You cannot save to file directly from T-SQL

Thanks

|||

You should do it at design time if possible.

You can try to send your stored procedure code as attachments in e-mail and next save this attachments or you can get stored procedure code using system stored procedure and save result to flat file output using SSIS package, You can also try to use Bulk copy?. You cannot save to file directly from T-SQL except if it will be CLR stored procedure which is probably best way to do it.

Thanks

|||What do you mean by CLR stored procedure ?|||

CLR stored procedure is new for SQL 2005 and allow you to create stored procedure or function in .net language, so you can access database and any available .net stuff, and good thing is that you can run it on SQL serer as standard SQL stored procedure (in the past you had extended stored procedures created in C++).

Thanks

|||

(1) You can also generate the scripts from the DB, Right click on DB -> All Tasks -> Generate Scripts.

(2) You can get the text for a stored proc from syscomments.

(3) You can probably write some application to get the text from syscomments and save it to a file.

|||

With the following query, I get all my SP and the text in the query result.

=====

USE

PDSNT

SELECT

name,text

FROM

sysobjects

INNER

JOINsyscomments

ON

sysobjects.id=syscomments.id

WHERE

xtype='p'AND NameLIKE'DEF%'

ORDER

BY NAME

=====

Next step would be to export them to .xml or .txt file.

Anyone can help?

Backing Up Stored Procedures

How do I Backup stored procedures?Backup the database which contains the stored procedures.
You backup everything in the database when you do a backup.
Not sure if you mean you want the stored procedures separate
from everything else or not but you could script out the
stored procedures if you need something along those lines.
-Sue
On Mon, 22 Mar 2004 10:34:36 -0800, "barb"
<anonymous@.discussions.microsoft.com> wrote:

>How do I Backup stored procedures?|||We do not need some of the default stored procedures.
Security docs say to drop. I want to backup before I drop
in case I need to add back at later date. How do I "script
out" the stored procedures? Thank you.

>--Original Message--
>Backup the database which contains the stored procedures.
>You backup everything in the database when you do a
backup.
>Not sure if you mean you want the stored procedures
separate
>from everything else or not but you could script out the
>stored procedures if you need something along those lines.
>-Sue
>On Mon, 22 Mar 2004 10:34:36 -0800, "barb"
><anonymous@.discussions.microsoft.com> wrote:
>
>.
>|||Right click on the db in Enterprise Manager and choose All Tasks - Generate
SQL Script. Here you can script them all or just selected ones.
Andrew J. Kelly SQL MVP
"barb" <anonymous@.discussions.microsoft.com> wrote in message
news:1198d01c4106d$70603750$a401280a@.phx
.gbl...
> We do not need some of the default stored procedures.
> Security docs say to drop. I want to backup before I drop
> in case I need to add back at later date. How do I "script
> out" the stored procedures? Thank you.
>
>
>
> backup.
> separate|||Thank You.
-- Andrew J. Kelly wrote: --
Right click on the db in Enterprise Manager and choose All Tasks - Generate
SQL Script. Here you can script them all or just selected ones.
Andrew J. Kelly SQL MVP
"barb" <anonymous@.discussions.microsoft.com> wrote in message
news:1198d01c4106d$70603750$a401280a@.phx
.gbl...
> We do not need some of the default stored procedures.
> Security docs say to drop. I want to backup before I drop
> in case I need to add back at later date. How do I "script
> out" the stored procedures? Thank you.
> backup.
> separate

Sunday, March 25, 2012

backing up everything to sql script

is there a way to back up the entire database, data, relations, tables, and
procedures to an sql script? and if so how do i do it? thanksBrian,
> is there a way to back up the entire database, data, relations,
> tables, and procedures to an sql script? and if so how do i do
> it? thanks
Yes, in Enterprise Manager. Right-click on the database, select All
Tasks | Generate SQL Script... from the menu.
Linda|||Brian,
Just one oversite - This does not get you the DATA.
You can back up the data using:
1) A full database backup - also gets you everything else
2) Detach database and file copy mdf, ndf, ldf files (or just stop SQL server rather than detach)
3) bcp
4) dts
5) Access import via odbc ( okay not so easy to get back, but still useful )
With 3) to 5) backup is on a table by table basis.
Regards
AJ
"lindawie" <lindawie@.my-deja.com> wrote in message news:OYUXTpEkDHA.976@.tk2msftngp13.phx.gbl...
> Brian,
> > is there a way to back up the entire database, data, relations,
> > tables, and procedures to an sql script? and if so how do i do
> > it? thanks
> Yes, in Enterprise Manager. Right-click on the database, select All
> Tasks | Generate SQL Script... from the menu.
> Linda
>

Saturday, February 25, 2012

Avoiding SQL Injection with Dynamic SQL

I am exclusively using Stored Procedures to access the database, i.e. there are no Ad-Hoc SQL statements anywhere in the C# code. However, one thing I need to be able to do is to allow filtering for data grids on my ASP.NET page. I want to do the filtering in the Stored Procedure using Dynamic SQL to set the WHERE clause. However, one fear of mine is SQL injection from the client. How can I avoid arbitrary SQL injection, yet still allow for a dynamic WHERE clause to be passed into the stored procedure?

Jason PachecoFrom herehttp://www.microsoft.com/technet/prodtechnol/sql/2000/maintain/sp3sec03.mspx

Preventing SQL Injection

So long as injected SQL code is syntactically correct, it will be impossible to programmatically detect tampering on the server side. You must therefore validate all user input on the client side, and force server-side type checking by calling parameterized stored procedures. Always validate user input by testing type, length, format, and range. Untested input can cause program errors, and may be used by hackers as a point of entry into your system. When implementing precautions against malicious input, consider the architecture and deployment scenarios of your application. Remember that programs designed to run in a secure environment can be copied to an insecure environment.

Validate All Input

The following suggestions should be considered best practices:
- Make no assumptions about the size, type, or content of the data received by your application. For example, evaluate:
- How will your application behave if an errant, or malicious, user enters a 10-megabyte MPEG file where your application expects a postal code?
- How will your application behave if a DROP TABLE statement is embedded in a text field?
- Test the size and data type of input, and enforce appropriate limits. This can help prevent deliberate buffer overruns.
- Test the content of string variables and accept only expected values. Reject entries containing binary data, escape sequences, and comment characters. This can help prevent script injection and can protect against some buffer overrun exploits.
- When working with XML documents, validate all data against its schema as it is entered.
- Never build Transact-SQL statements directly from user input.
- Use stored procedures to validate user input.
- In multi-tiered environments, all data should be validated before admission to the trusted zone. Data that does not pass the validation process should be rejected, and an error returned to the previous tier.
- Implement multiple layers of validation. Precautions you take against casually malicious users may be ineffective against expert hackers. The best practice is to validate input in the user interface, and then at all subsequent points at which it crosses a trust boundary.

For example, data validation in a client-side application may prevent simple script injection; however, if the next tier assumes that its input has already been validated, any hacker capable of bypassing your client can have unrestricted access to your system.
- Never concatenate user input that is not validated. String concatenation is the primary point of entry for script injection.
- Do not accept the following strings in fields from which file names may be constructed: AUX, CLOCK$, COM1 through COM8, CON, CONFIG$, LPT1 through LPT8, NUL, and PRN.

When possible, reject input that contains the following potentially dangerous characters.
Input characterMeaning in Transact-SQL

; Query delimiter

' Character data string delimiter

-- Comment delimiter

/* ... */ Comment delimiters. Text between /* and */ is not evaluated by the server.

Xp_ Begins the name of catalog extended stored procedures such as xp_cmdshell.

Use Type-Safe SQL Parameters

The Parameters collection in SQL Server provides type checking and length validation. If you use the Parameters collection, input is treated as a literal value rather than executable code. An additional benefit of using the Parameters collection is that you can enforce type and length checks. Values outside of the range will trigger an exception. The following code fragment illustrates using the Parameters collection:

SqlDataAdapter myCommand = new SqlDataAdapter("AuthorLogin", conn);
myCommand.SelectCommand.CommandType = CommandType.StoredProcedure;
SqlParameter parm = myCommand.SelectCommand.Parameters.Add(
"@.au_id", SqlDbType.VarChar, 11);
parm.Value = Login.Text;

In this example, the @.au_id parameter is treated as a literal value rather than executable code. This value is checked for type and length. If the value of @.au_id does not conform to the specified type and length constraints, an exception will be thrown.

Use Parameterized Input with Stored Procedures

Stored procedures may be susceptible to SQL injection if they use unfiltered input. For example, the following code is vulnerable:

SqlDataAdapter myCommand =
new SqlDataAdapter("LoginStoredProcedure '" +
Login.Text + "'", conn);

If you use stored procedures, you should use parameters as their input.

Use the Parameters Collection with Dynamic SQL

If you cannot use stored procedures, you can still use parameters, as shown below.

SqlDataAdapter myCommand = new SqlDataAdapter(
"SELECT au_lname, au_fname FROM Authors WHERE au_id = @.au_id", conn);
SQLParameter parm = myCommand.SelectCommand.Parameters.Add("@.au_id",
SqlDbType.VarChar, 11);
Parm.Value = Login.Text;

Filtering Input

Filtering input may also be helpful in protecting against SQL injection by removing escape characters, but due to the large number of characters that may pose problems it is not a reliable defense. The following snippet searches for the character string delimiter.

private string SafeSqlLiteral(string inputSQL)
{
return inputSQL.Replace("'", "''");
}

LIKE Clauses

Note that if you are using a LIKE clause, wildcard characters still need to be escaped:

s = s.Replace("[", "[[]");
s = s.Replace("%", "[%]");
s = s.Replace("_", "[_]");|||

Many thanks to you DarrellNorton,

Very helpfull information.
this was my posthttp://forums.asp.net/926297/ShowPost.aspx

BR

Friday, February 24, 2012

avoid warning

We use a script in our build process to create a database. A single
script creates entire database, including stored procedures. We
occasionally
get a warning message "cannot create entry in sysdepends as .....
the procedure will still be created". I believe this is a harmless
warning
and happens because of the order of creation of stord procedure. Is
there a way to disable this warning.
See "set ansi_warnings" in BOL.
use northwind
go
set ansi_warnings off
go
create procedure proc1
as
select * from t1
go
set ansi_warnings on
go
drop procedure proc1
go
AMB
"Data Cruncher" wrote:

> We use a script in our build process to create a database. A single
> script creates entire database, including stored procedures. We
> occasionally
> get a warning message "cannot create entry in sysdepends as .....
> the procedure will still be created". I believe this is a harmless
> warning
> and happens because of the order of creation of stord procedure. Is
> there a way to disable this warning.
>
|||Sorry,
It seems that this option does not help.
AMB
"Alejandro Mesa" wrote:
[vbcol=seagreen]
> See "set ansi_warnings" in BOL.
> use northwind
> go
> set ansi_warnings off
> go
> create procedure proc1
> as
> select * from t1
> go
> set ansi_warnings on
> go
> drop procedure proc1
> go
>
> AMB
> "Data Cruncher" wrote:
|||I don't think there's a way to shut off the warning outside of
creating your script with sub procs being compiled before the
calling procs.
For all intents and purposes, it's harmless for the reason
you stated. Of course, it's not harmless if the main procedure,
in fact, doesn't get created!
"Data Cruncher" <dcruncher4@.netscape.net> wrote in message
news:1116249702.395329.63480@.g47g2000cwa.googlegro ups.com...
> We use a script in our build process to create a database. A single
> script creates entire database, including stored procedures. We
> occasionally
> get a warning message "cannot create entry in sysdepends as .....
> the procedure will still be created". I believe this is a harmless
> warning
> and happens because of the order of creation of stord procedure. Is
> there a way to disable this warning.
>

avoid warning

We use a script in our build process to create a database. A single
script creates entire database, including stored procedures. We
occasionally
get a warning message "cannot create entry in sysdepends as .....
the procedure will still be created". I believe this is a harmless
warning
and happens because of the order of creation of stord procedure. Is
there a way to disable this warning.See "set ansi_warnings" in BOL.
use northwind
go
set ansi_warnings off
go
create procedure proc1
as
select * from t1
go
set ansi_warnings on
go
drop procedure proc1
go
AMB
"Data Cruncher" wrote:
> We use a script in our build process to create a database. A single
> script creates entire database, including stored procedures. We
> occasionally
> get a warning message "cannot create entry in sysdepends as .....
> the procedure will still be created". I believe this is a harmless
> warning
> and happens because of the order of creation of stord procedure. Is
> there a way to disable this warning.
>|||Sorry,
It seems that this option does not help.
AMB
"Alejandro Mesa" wrote:
> See "set ansi_warnings" in BOL.
> use northwind
> go
> set ansi_warnings off
> go
> create procedure proc1
> as
> select * from t1
> go
> set ansi_warnings on
> go
> drop procedure proc1
> go
>
> AMB
> "Data Cruncher" wrote:
> > We use a script in our build process to create a database. A single
> > script creates entire database, including stored procedures. We
> > occasionally
> > get a warning message "cannot create entry in sysdepends as .....
> > the procedure will still be created". I believe this is a harmless
> > warning
> > and happens because of the order of creation of stord procedure. Is
> > there a way to disable this warning.
> >
> >|||I don't think there's a way to shut off the warning outside of
creating your script with sub procs being compiled before the
calling procs.
For all intents and purposes, it's harmless for the reason
you stated. Of course, it's not harmless if the main procedure,
in fact, doesn't get created!
"Data Cruncher" <dcruncher4@.netscape.net> wrote in message
news:1116249702.395329.63480@.g47g2000cwa.googlegroups.com...
> We use a script in our build process to create a database. A single
> script creates entire database, including stored procedures. We
> occasionally
> get a warning message "cannot create entry in sysdepends as .....
> the procedure will still be created". I believe this is a harmless
> warning
> and happens because of the order of creation of stord procedure. Is
> there a way to disable this warning.
>

avoid warning

We use a script in our build process to create a database. A single
script creates entire database, including stored procedures. We
occasionally
get a warning message "cannot create entry in sysdepends as .....
the procedure will still be created". I believe this is a harmless
warning
and happens because of the order of creation of stord procedure. Is
there a way to disable this warning.See "set ansi_warnings" in BOL.
use northwind
go
set ansi_warnings off
go
create procedure proc1
as
select * from t1
go
set ansi_warnings on
go
drop procedure proc1
go
AMB
"Data Cruncher" wrote:

> We use a script in our build process to create a database. A single
> script creates entire database, including stored procedures. We
> occasionally
> get a warning message "cannot create entry in sysdepends as .....
> the procedure will still be created". I believe this is a harmless
> warning
> and happens because of the order of creation of stord procedure. Is
> there a way to disable this warning.
>|||Sorry,
It seems that this option does not help.
AMB
"Alejandro Mesa" wrote:
[vbcol=seagreen]
> See "set ansi_warnings" in BOL.
> use northwind
> go
> set ansi_warnings off
> go
> create procedure proc1
> as
> select * from t1
> go
> set ansi_warnings on
> go
> drop procedure proc1
> go
>
> AMB
> "Data Cruncher" wrote:
>|||I don't think there's a way to shut off the warning outside of
creating your script with sub procs being compiled before the
calling procs.
For all intents and purposes, it's harmless for the reason
you stated. Of course, it's not harmless if the main procedure,
in fact, doesn't get created!
"Data Cruncher" <dcruncher4@.netscape.net> wrote in message
news:1116249702.395329.63480@.g47g2000cwa.googlegroups.com...
> We use a script in our build process to create a database. A single
> script creates entire database, including stored procedures. We
> occasionally
> get a warning message "cannot create entry in sysdepends as .....
> the procedure will still be created". I believe this is a harmless
> warning
> and happens because of the order of creation of stord procedure. Is
> there a way to disable this warning.
>

avoid using cursors

Hi All,
I want to avoid using cursors and loops in stored procedures.
Please suggest alternate solutions with example (if possible).

Any suggestion in these regards will be appreciated.

Thanks in advance,
T.S.NegiHere is a sample:
http://www.extremeexperts.com/SQL/A...TSQLResult.aspx

--
HTH,
Vinod Kumar
MCSE, DBA, MCAD, MCSD
http://www.extremeexperts.com

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp

"T.S.Negi" <tilak.negi@.mind-infotech.com> wrote in message
news:a1930058.0502132109.268ae0dd@.posting.google.c om...
> Hi All,
> I want to avoid using cursors and loops in stored procedures.
> Please suggest alternate solutions with example (if possible).
> Any suggestion in these regards will be appreciated.
>
> Thanks in advance,
> T.S.Negi|||Loops and cursors are just programming constructs, not actual problems
to be solved, so there is no generic solution or example to show how to
avoid them. You should try to avoid or minimize the use of loops and
cursors in SQL and this is done by writing standard set-based code:
SELECT, UPDATE, DELETE and INSERT statements that operate on sets of
rows rather than one row at a time. The actual details will depend on
exactly what you want to achieve.

If you require hlep with a specific problem then please post more
details as described in:
http://www.aspfaq.com/etiquette.asp?id=5006

--
David Portas
SQL Server MVP
--|||Unfortunately, all the examples in that article are loops!

--
David Portas
SQL Server MVP
--|||tilak.negi@.mind-infotech.com (T.S.Negi) wrote:

>Hi All,
>I want to avoid using cursors and loops in stored procedures.
>Please suggest alternate solutions with example (if possible).

Off at a tangent:

I see many times in these groups (and elsewhere) that cursors should
be avoided. As a comparative newbie can someone explain to me the
reasons for this.
--
HTML-to-text and markup removal with Detagger
http://www.jafsoft.com/detagger/|||There are plenty of good reasons to use declarative, set-based SQL code
instead of cursors. The reason most usually given is performance. SQL
Server, like other SQL databases, is designed primarily for
set-at-a-time rather than row-at-a-time operations. Cursors are
typically very slow, although performance obviously varies considerably
depending on what you are doing. Paradoxically, it is also true to say
that there is a small class of problems for which cursors are faster
than any set-based solution. In a well-designed database those
situations are uncommon in my experience and you would be well-advised
to get a second opinion if you think you have come across such a case.
Performance and locking issues with cursors tend to mean they are far
less scalable than the set-based alternatives so even if they work for
you today they may not be a viable solution in future.

Besides performance there are other good reasons to use set-based code:
The declarative code is usually much more concise and therefore easier
to develop, inspect, test and maintain; It's more likely to be
portable to other database platforms; SQL professionals (good ones
using TSQL anyway) tend to write cursors seldom and so are likely to be
more comfortable and more productive writing set-based code; Set-based
code avoids or tends to show-up some of the logical anomalies and
design problems that can lie hidden and unnoticed in procedural cursor
code.

A legitimate place to use a cursor is for something inherently
procedural (typically admin tasks such as managing backups, sending
emails or importing/exporting files) but in general in an RDBMS you
should assume the solution to any data-manipulation problem will be
set-based unless expert analysis proves otherwise. That's why I would
class cursors as a feature for advanced users only. If you find
yourself writing cursors regularly then it's time to rethink what you
are doing or maybe go on a course to learn grown-up SQL (too many
cursors are written by programmers who don't know better techniques)
:-)

--
David Portas
SQL Server MVP
--|||On Tue, 15 Feb 2005 14:21:03 +0000, John A Fotheringham wrote:

>I see many times in these groups (and elsewhere) that cursors should
>be avoided. As a comparative newbie can someone explain to me the
>reasons for this.

Hi John,

SQL Server is heavily optimized towards set-based operations, where you
use one single query to specify what you want and let SQL Server work out
the best strategy to satisfy your request. That's why SQL is called a
declarative language (you declare the intended results, not the way to get
there, as opposed to procedural languages (where you specify the procedure
to get the intended results).

Using cursors is forcing a procedural approach on SQL. You still use a
query to specify the rows you want to fetch (the declarative part), but
then you fetch one, do something with it and fetch the next - that is
purely procedural.

It is my experience that at least 99% of all existing cursor-based code
can be replaced by set-based code. In most cases, the replacing set-based
code is shorter (less lines), easier to read, understand and maintain (at
least after you've mastered the learning curve to switch from procedural
thinking to declarative thinking) and -most important- performs much
faster.

For the remaining less than one percent, cursors are indeed the best
solution. I won't say that cursors should _always_ be avoided. But I will
say that they are to be used as a final resort only - and it's always wise
to get a second opinion first. Newsgroups are a great place to explain
your problem and ask if others agree that this particular problem can't be
solved with declarative code. In most cases, you'll get a surprising
answer - and if you take the trouble to not only copy and adapt the code
posted, but also to try to understand it, you'll get a great learning
experience thrown in for free!

Best, Hugo
--

(Remove _NO_ and _SPAM_ to get my e-mail address)|||One trick I have started to use:
Whenever I need to iterate in a procedure I have a table that I have
created with only one column like so:

CREATE TABLE [Numbers] (
[PkNumber] [int] IDENTITY (1, 1) NOT NULL ,
CONSTRAINT [Pk_Number] PRIMARY KEY CLUSTERED
(
[PkNumber]
) ON [PRIMARY]
) ON [PRIMARY]
GO

Declare @.i as int
set @.i = 0
while @.i <= 10000
begin
Insert into dbo.Numbers Default values
set @.i = @.i + 1
end

GO

Now with this table I can query against it like it were a loop but
still remaining set based.
So for instance If I were trying to Schedule a date every 7 days for
the next year I could do something like

insert into dates(dates)
Select DateAdd(Day,pk_Number * 7,getdate())
from Numbers
where pk_number < 366

Just a little trick

Tal McMahon|||Hugo Kornelis (hugo@.pe_NO_rFact.in_SPAM_fo) writes:
> It is my experience that at least 99% of all existing cursor-based code
> can be replaced by set-based code. In most cases, the replacing set-based
> code is shorter (less lines), easier to read, understand and maintain (at
> least after you've mastered the learning curve to switch from procedural
> thinking to declarative thinking) and -most important- performs much
> faster.

Our system has its fair share ot iterative processing, and maybe the
most common good reason to use a cursor is that you have a stored
procedure that performs an operation on a single set of values and
you want to reuse that logic.

If all the procedure performs is a simple update, or a plain insert,
there's little reason to keep the procedure.

But we have core procedures that performs a lot of updates and inserts
(including validations) for a bunch of in-parameters. Rewriting such
a procedure to operate set-based from an input table is a major task.
We've done it in one case. I seem to recall that the time estimate was
200 h, and I think we exceeded that. The result is a monster procedure
on 3000 lines that uses 43 table variables.

This particular rewrite was necessary given some of the volumes that can
occur in some of the iterations with its predecessor. But I can tell
you that I am not going to initiate more rewrites, just for the sake
of it.

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp|||On Tue, 15 Feb 2005 22:57:01 +0000 (UTC), Erland Sommarskog wrote:

(snip)
>This particular rewrite was necessary given some of the volumes that can
>occur in some of the iterations with its predecessor. But I can tell
>you that I am not going to initiate more rewrites, just for the sake
>of it.

Hi Erland,

I see what you mean and I totally agree: if it works and it is not "too"
slow, then there is abolutely no reason to change it.

The often prohibitive cost of rewrites is just another reason for me to
continue trying to convince everybody to write set-based code right from
the off.

Best, Hugo
--

(Remove _NO_ and _SPAM_ to get my e-mail address)|||I have a book called SQL PROGRAMMING STYLE that should be published by
2005 April that has some chapters on how to think in Sets instead of
procedures. There is no single, magic answer.|||>> I see many times in these groups (and elsewhere) that cursors should
be avoided. As a comparative newbie can someone explain to me the
reasons for this. <<

All of the performance reasons that portas, Kornelis and Sommarskog
gave are the usual reasons. But don't for get the lack of portability!

In spite of the SQL standards, cursors are still VERY proprietary. But
even if they were all perfectly aligned, there are enough
"implementation dependent" things to screw you over. For example,
there is a warning that is raised when a GROUP BY has a NULL removed
from one of the groups. Sounds good, since I might not want to run a
report if I have missing data in one or more groups ("And where the
hell is Smith's sales figures??!")

But this warning can be raised at DECLARE CURSOR, OPEN cursor and/or
FETCH cursor. This is going to change application program logic quite
a bit.|||Except, of course, that this schedules the event every 7 days for the
next 7 years...

Your where clause should be:
where (pk_number * 7) < 366|||Erland Sommarskog <esquel@.sommarskog.se> wrote:

>Hugo Kornelis (hugo@.pe_NO_rFact.in_SPAM_fo) writes:
>> It is my experience that at least 99% of all existing cursor-based code
>> can be replaced by set-based code. In most cases, the replacing set-based
>> code is shorter (less lines), easier to read, understand and maintain (at
>> least after you've mastered the learning curve to switch from procedural
>> thinking to declarative thinking) and -most important- performs much
>> faster.
>Our system has its fair share ot iterative processing, and maybe the
>most common good reason to use a cursor is that you have a stored
>procedure that performs an operation on a single set of values and
>you want to reuse that logic.

This is the only situation in which I've used a cursor so far.

I have a trigger set on insert into one table, and for each inserted
record I want to use it's contents to create and/or update the
contents of a record in a second table.

I've written a procedure to do the fairly complex update from one
record to another, and I call that procedure from inside a fairly
simple cursor loop that forms the main body of the trigger procedure.

I'm not too worried about cursor overheads here, because in general
only one record at a time is being inserted into the first table.

At the time I wrote this cursors seemed the only (and natural) way to
iterate through the records in the "inserted" table, which in this
instance is what I need to do as each record has to be processed
separately.

If there's a better/more appropriate way of doing this I'd be
interested to hear it. A lot of the "set-based" solutions I see here
just seem to be implementing loops using a table and from a purely
programming point of view (my background) seem a counter-intuitive way
of doing things.

--
HTML-to-text and markup removal with Detagger
http://www.jafsoft.com/detagger/|||I would recommend that you don't use cursors in triggers. As already
discussed, if you have a legacy of procedural code that works on one
row at a time then yes, you may be forced to call that code in a loop
just because of the cost of rewriting your procedure in set-based form.
That's a pity because some day you may want to update more than one row
at a time and anyway you really don't need the overhead of a cursor
declaration in a trigger, even for a single row.

> A lot of the "set-based" solutions I see here
> just seem to be implementing loops using a table and from a purely
> programming point of view (my background) seem a counter-intuitive
way
> of doing things.

I don't know what you are referring to. Maybe you have an example? If
you mean using WHILE loops and SELECT statements in place of cursors
then yes, that is just cursor in disguise and all my comments about
cursors apply equally to those other row-by-row constructs.

It is true that declarative SQL requires a slightly different mindset
and it is often noted that procedural programmers find these methods
counter-intuitive. However, the relational model and SQL are the
dominant industry database standards with good reason and that is
hopefully a good enough incentive for the programmer to learn the
standard techniques and best-practices, aside from the very practical
considerations already explained.

--
David Portas
SQL Server MVP
--|||> If there's a better/more appropriate way of doing this I'd be
> interested to hear it.

Very likely there is a better way but we'll need more details first:
http://www.aspfaq.com/etiquette.asp?id=5006

--
David Portas
SQL Server MVP
--|||"David Portas" <REMOVE_BEFORE_REPLYING_dportas@.acm.org> wrote:

>I would recommend that you don't use cursors in triggers. As already
>discussed, if you have a legacy of procedural code that works on one
>row at a time then yes, you may be forced to call that code in a loop
>just because of the cost of rewriting your procedure in set-based form.
>That's a pity because some day you may want to update more than one row
>at a time and anyway you really don't need the overhead of a cursor
>declaration in a trigger, even for a single row.

So how would you advise to select a single row from the inserted table
without using a cursor?

>> A lot of the "set-based" solutions I see here
>> just seem to be implementing loops using a table and from a purely
>> programming point of view (my background) seem a counter-intuitive
>way
>> of doing things.
>I don't know what you are referring to. Maybe you have an example? If
>you mean using WHILE loops and SELECT statements in place of cursors
>then yes, that is just cursor in disguise and all my comments about
>cursors apply equally to those other row-by-row constructs.

Well that's what I thought. Most of these approaches seem to be a
loop through table, and it's not obvious (to the newbies) that this
would be more efficient than a cursor.

>It is true that declarative SQL requires a slightly different mindset
>and it is often noted that procedural programmers find these methods
>counter-intuitive. However, the relational model and SQL are the
>dominant industry database standards with good reason and that is
>hopefully a good enough incentive for the programmer to learn the
>standard techniques and best-practices, aside from the very practical
>considerations already explained.

I'm not disputing this, just asking questions so I can better get into
the correct mindset for SQL.
--
HTML-to-text and markup removal with Detagger
http://www.jafsoft.com/detagger/|||"David Portas" <REMOVE_BEFORE_REPLYING_dportas@.acm.org> wrote:

>> If there's a better/more appropriate way of doing this I'd be
>> interested to hear it.
>Very likely there is a better way but we'll need more details first:
>http://www.aspfaq.com/etiquette.asp?id=5006

Well I was really just asking a generic question. The tables involved
are fairly lengthy (although as far as the logic goes only a few
fields apply) and I didn't think to fill my post with all the details.
I wasn't seeking a particular solution, just asking the general
question.

In essence I have

CREATE TABLE transaction
(
IDint IDENTITY(1,1),

tsdatetime
jobvarchar(20)
statuschar(1)
...
other transaction fields
...
)

CREATE TABLE jobs
(
jobvarchar(20)
statuschar(1)
last_updatedatetime
...
other job fields
...
)

Each time a transaction comes in I use the details in the transaction
to update the jobs table. If it's a new job I create a new record,
otherwise I perform an update. The nature of the update can depend
on the value of the new status, so that depending on the status
different values amongst the "other transaction fields" will cause
different updated for the "other job fields". Further processing may
occur for some status codes.

To achieve this I wrote a "processTrn" procedure which takes a single
transaction and executes all the (largely procedural) updates.

To call this procedure I created a trigger on the transactions table,
and it's there that I use a cursor to go through the "inserted" table
to extract each new record in turn and call the procedure on it.

To my mind this is a naturally loop+procedural process.

Note, because the transactions table is added to 1 record at a time by
an external process, the actual cursor loops in this case are usually
for a single record.

--
HTML-to-text and markup removal with Detagger
http://www.jafsoft.com/detagger/|||> So how would you advise to select a single row from the inserted
table
> without using a cursor?

I *wouldn't* select a single row. The problem is precisely to AVOID
processing single rows of data and process the whole set of data at
once. This is what we mean by "set-based" code. By putting business
logic in a stored proc that opeartes only on one row at a time you have
forced yourself to call that proc once for each row. It likely doesn't
have to be that way but since you haven't explained what the proc does
I can't really advise on the alternatives.

--
David Portas
SQL Server MVP
--|||> If it's a new job I create a new record

INSERT INTO Jobs (job, ...)
SELECT job, ...
FROM Inserted
WHERE NOT EXISTS
(SELECT *
FROM Jobs
WHERE job = Inserted.job)

Note however that you should generally avoid duplicating data between
tables (except for key columns). Duplicated data is a problem in a
relational database and the goal of Normalization in db design is to
eliminate it. You should also aim to eliminate transitive dependencies
- i.e. columns that can always be derived from data in other (non-key
columns) - doing so reduces the need for triggers.

> otherwise I perform an update

UPDATE Jobs
SET ... ?
WHERE EXISTS
(SELECT *
FROM Inserted
WHERE job = Jobs.job AND ... ?)

> The nature of the update can depend
> on the value of the new status, so that depending on the status
> different values amongst the "other transaction fields" will cause
> different updated for the "other job fields".

That's not much information to go on but you could probably use CASE
expressions for this.

--
David Portas
SQL Server MVP
--|||"David Portas" <REMOVE_BEFORE_REPLYING_dportas@.acm.org> wrote:

>> If it's a new job I create a new record
>INSERT INTO Jobs (job, ...)
> SELECT job, ...
> FROM Inserted
> WHERE NOT EXISTS
> (SELECT *
> FROM Jobs
> WHERE job = Inserted.job)

Thanks. I begin to see how the procedural approach can be avoided.

--
HTML-to-text and markup removal with Detagger
http://www.jafsoft.com/detagger/|||LOL,
yeah I guess you are right must have been late.|||John A Fotheringham (jafsoft@.gmail.com) writes:
> This is the only situation in which I've used a cursor so far.
> I have a trigger set on insert into one table, and for each inserted
> record I want to use it's contents to create and/or update the
> contents of a record in a second table.
> I've written a procedure to do the fairly complex update from one
> record to another, and I call that procedure from inside a fairly
> simple cursor loop that forms the main body of the trigger procedure.
> I'm not too worried about cursor overheads here, because in general
> only one record at a time is being inserted into the first table.

Normally, it is not a good idea ot have a cursor in a trigger, but if
you know your business well enough to be confident that one row-at-a-time
is the normal case, this sounds like a sound approach to me. From a
theoretical point of view, the trigger certainly could be improved. But as
long as the penalty for the cursor is low or non-existent, it seems very
difficult to justify spending time on a more complex solution.

That cannot be denied, if you want to encapsulate logic by putting
it in stored procedures, this is easier for scalar values than for
sets of values, since procedure parameters are scalar. It is possible
to work around this by sharing temp tables or similar, but only does
this increase complexity. You can also get recompilation issues that
are bad for performance.

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp