|
|
|
SSC Eights!
      
Group: General Forum Members
Last Login: Yesterday @ 9:18 PM
Points: 802,
Visits: 740
|
|
Girish Bhat (4/15/2009) Hi Thomas,
Your point is well taken. For the specific example you have mentioned, you could use:
sp_MSforeachtable @command1 = "Alter Table ? Alter Column Foo nvarchar(10)", @whereand = "and OBJECT_ID in (select object_ID from sys.columns where name = 'Foo')"
sp_MSforeachtable is pretty awful, it calls sp_MSforeach_worker internally to use the cursor it declares; generally you will get far more efficient code by declaring your own cursor and using it instead of letting MS do it for you. Probably you will be more efficient still using dynamic SQL to avoid a cursor altogether.
Tom Thomson Na tog mi gun tuit mi ach ma thuiteas tog! Thig crìoch air an t-saoghal ach mairidh gaol is ceòl
|
|
|
|
|
SSC Rookie
      
Group: General Forum Members
Last Login: Friday, March 12, 2010 2:01 PM
Points: 26,
Visits: 80
|
|
Tom.Thomson (4/29/2009)
gautamsheth2000 (4/13/2009)
Should use this code  Select count(*) From master.sys.columns C1 CROSS JOIN master.sys.columns C2 That's far too slow Try instead: select power(count(*),2) from master.sys.columns Comparing equivalent code on SQL Server 2000 indicates that this takes about 25% of the time your cross join method takes, if there are about 5000 rows in the columns table.
Nice one !
|
|
|
|
|
SSC Rookie
      
Group: General Forum Members
Last Login: Friday, March 12, 2010 2:01 PM
Points: 26,
Visits: 80
|
|
gserdijn (4/14/2009) select square(count(1)) From master.sys.columns C1
Oops! I had missed that one.
Nice !
|
|
|
|
|
SSC Eights!
      
Group: General Forum Members
Last Login: Yesterday @ 9:18 PM
Points: 802,
Visits: 740
|
|
RBarryYoung (4/15/2009) Just because pure set-based SQL may not be sufficient for a particular task does not mean that that justifies Cursors or loops in SQL. There are still a lot of miles between the two and a lot of other options that are not even on the same scale.
Often the best solution is a loop - in fact I can't see a way of doing batching/chunking with delays between batches without using a loop. I usually express my loop as a schedule in MSDB, and I usualy use SQL to create that schedule rather than going through the job creation wizard, since the job may have to be created at every customer site and running some SQL is a lot less time consuming than using the wizard. Would it be reasonable to claim that I'm not writing loops in SQL? Maybe, but a loop is what I want for my solution and I'm telling the SQL system what loop I want, so if SQL as a declarative language that's writing a loop in SQL.
I'm being a bit pedantic here, I know, but I,m doing it because think your over-strong denial of the usefulness of loops detracts from your message.
Now if instead of loops you had said "while loops" that would be a different story, of course (I use those too sometimes, in SQL 2000, but only because 8000 isn't big enough no need in SQL 2005 and onwards).
Tom Thomson Na tog mi gun tuit mi ach ma thuiteas tog! Thig crìoch air an t-saoghal ach mairidh gaol is ceòl
|
|
|
|
|
SSC Eights!
      
Group: General Forum Members
Last Login: Yesterday @ 9:18 PM
Points: 802,
Visits: 740
|
|
WayneS (4/18/2009) I just thought of something that I wish I had included with my original post. Programming languages have evolved. 15 years ago, you had plain old programming languages, complete with procedural ways of doing things. Then came object-oriented programming languages. To be a good OOP programmer, one had to start thinking of things as objects, and you had to deal with OOP principals, such as events, properties, encapusaltion and polymorphism. This thought shift did not occur overnight - you had to immerse yourself in it and work at it. Not all programmers could make this shift, and for others it took a long time before the light clicked on behind their eyes and they understood it.
Off topic, bu IO can't let such basic nonsense pass.
15 years ago is 1994. I could just mention that that's 10 years after Cardelli's paper on "The Semantics of Multiple Inheritance" but that doesn't really bring out the enormity of the ignorance of computer languages dispayed in the quoted text.
Object Oriented languages are a bit older than 15 years : Simula(1962), Simula I (1965), Smalltalk(1971) are obvious examples. Languages allowing no visibility of the internal implementation of a type (ABstract Data Type languages, Algebraic Datatype languages) abounded in the 1960s (and this characteristic - often expressed as communication between objects only bt message passing - is the basis of the OO paradigm). Even the language most often (mis-)called Object Oriented today (C++) dates from 1982, a dozen tears before 1994, and Soundstrup's "C with Classes" upon which it was based was 1979. Besides, are functional languages (Lisp, 1958), logic languages (Prolog,1972), Actor languages (1970s), Process languages (CCS, 1980 - unless you count the 1978 paper-only version of CSP), Temporal Logic languages (before 1987 - i was using one then), the pi calculus (1989: at least half a dozen successor languages exist and are in use today, and I think this is on a rather different level from proces languages bilke CCS and CSP), mark-up languages (HTML -1991 - was based on SQML which in turn had it's roots in GML - early 60s).
So how many of all these object oriented languages and declarative languages and so on do you want to say are "plain old programming languages, complete with procedural ways of doing things"? It's true of "C with classes" and C++ of course, but I don't think it's true of any of the others.
Tom Thomson Na tog mi gun tuit mi ach ma thuiteas tog! Thig crìoch air an t-saoghal ach mairidh gaol is ceòl
|
|
|
|
|
SSChampion
        
Group: General Forum Members
Last Login: Yesterday @ 11:25 PM
Points: 20,175,
Visits: 13,708
|
|
Well stated... but doesn't that show that embracing OOP took even longer for most folks? I believe that was the real point trying to be made.
--Jeff Moden "RBAR is pronounced "ree-bar" and is a "Modenism" for "Row-By-Agonizing-Row".
"Data isn't the only thing that's supposed to have Integrity."
First step towards the paradigm shift of writing Set Based code: Stop thinking about what you want to do to a row... think, instead, of what you want to do to a column."
For better, quicker answers on T-SQL questions, click on the following... http://www.sqlservercentral.com/articles/Best+Practices/61537/
For better answers on performance questions, click on the following... http://www.sqlservercentral.com/articles/SQLServerCentral/66909/
|
|
|
|
|
SSCrazy Eights
        
Group: General Forum Members
Last Login: Wednesday, March 17, 2010 11:21 AM
Points: 9,104,
Visits: 8,528
|
|
Tom.Thomson (4/29/2009)
dbishop (4/14/2009) That is the point I was making. The author assumed that by changing his code from the individual steps (procedures) to Cookies, with chocolate chips, all of a sudden it was no longer procedural. I was trying to point out the falisy of that statement.
The trouble with this statement is that Barry made it absolutely clear which sense of the word "declarative" he was using. There are numerous different definitions of "declarative", but Barry was very clear: declarative in his sense means specifying the result you want (chocolate chip cookies) rather than specifying a method of achieving it (make the mix, bake it). You've fallen into the trap of saying that "the desired result is cookies with chocolate chips" means the same as "make a cookie mix and bake it to get cookies with chocolate chips" but they are clearly different: the former leaves you the choice between buying a bag of cookies, cooking your own cookies, or commissioning someone else to cook them for you (and a few other methods, of course); the latter requires you to cook them, not buy them or get someone else to make them. So the former is not at all procedural - how can it be, when it doesn't constrain the procedure for achieving the end result, it only constrains the end result? Excellent post Tom, one of my favorite ever. I should get you to do all of my public statements when I am sick or unavailable. 
However, I don't completely agree that SQL is actually declarative in Barry's sense, although a very large subset of it is. There are things that I can only express by an ordered sequence of statements - for example if I want to update several tables (unless there are some new language extensions I haven't heard about yet) - particularly if later updates depend on some characteristic of the earlier ones (total number of rows affected so far, for example). I completely agree. In fact, I am trying to get folks to stop using the most procedural parts of SQL. And yes, although there are limited ways to do multiple output tables in 2005 (and some better ones in 2008), for the most part you still need Sequence (first of the three procedural structures) to do this, though usually there isn't even a true need for sequencing them (if only we had the legendary Simultaneous control structure).
The fact that there are procedural elements in Transact SQL is pretty evident when you consider that one of our primary code structures is called a "Stored Procedure".
Something that SQL could usefully acquire from other declarative languages is a MAP operator (to map a stored procedure or an extended stored procedure over a table where each row represents a set of parameters for it, with no defined order in the absence of an order by clause). This would be much cleaner than the current game of building a string of commands and using exec SQL on it, and on cases where the order clause was absent it would allow parallelism that isn't achievable with exec(SQL) (since teh execution of a series of SQL statements is serial, although parallelism can happen within an individual statement). It might also be good to pick up the REDUCE operator from the same school - seems rather better than the current "select @v = expr involving @v from ..." way of doing reduce, and may add extra flexibility (and why does @v in that have to be a scalar variable? perhaps it's because tables are no "first class objects" in SQL?). Yep, MAP would be a great way to formalize (and allow for optimization of) the dynamic SQL approach to executing a sProc for every row in a set.
REDUCE is a bit more complicated. The current pseudocursor tricks could do everything that we wanted and more if Microsoft would just A) formalize an ordering/grouping syntax, B) allow mixed data & variable SELECTS, at all levels and C) just fully support what they have already been implementing for years anyway. Heck if we could get this, then we could throw away the problematic UPDATE version and we wouldn't need a new REDUCE operator at all. Now true, pseudocursors are still fairly procedural, but they are very constrained and contained so they are only about a 7 compared to the 10 of Cursor & WHILE loops.
But there is another way that Microsoft could go here that would be even better than REDUCE or pseudocursors: Allow user-defined Aggregate (including order-sensitive) and Windowed Aggregate functions in T-SQL. You can do half of this now with CLR, however in T-SQL you could actually require declarative set-based definitions.
-- RBarryYoung, (302)375-0451 blog: MovingSQL.com, Twitter: @RBarryYoung Proactive Performance Solutions, Inc. "Performance is our middle name."
|
|
|
|
|
SSCrazy Eights
        
Group: General Forum Members
Last Login: Wednesday, March 17, 2010 11:21 AM
Points: 9,104,
Visits: 8,528
|
|
Tom.Thomson (4/30/2009)
RBarryYoung (4/15/2009) Just because pure set-based SQL may not be sufficient for a particular task does not mean that that justifies Cursors or loops in SQL. There are still a lot of miles between the two and a lot of other options that are not even on the same scale.Often the best solution is a loop - Tom: You take issue with me on several points in this post, but I am not convinced that we actually differ on most of them. For instance:... in fact I can't see a way of doing batching/chunking with delays between batches without using a loop. Here's the strongest statement that I make on this from the article:Let me say that again so that there is no uncertainty: As of SQL Server 2005, the only reason to use Cursors is if you actually want to slow down your code (for instance to do a big update in chunks). I have no objection to using Cursors or While loops for chunking because the purpose of chunking is to slow down a large operation so that it does not impede the rest of the system.
Of course, as you next imply, Cursors and While loops are not the only way to do that: I usually express my loop as a schedule in MSDB, and I usualy use SQL to create that schedule rather than going through the job creation wizard, since the job may have to be created at every customer site and running some SQL is a lot less time consuming than using the wizard. Would it be reasonable to claim that I'm not writing loops in SQL? Maybe, but a loop is what I want for my solution and I'm telling the SQL system what loop I want, so if SQL as a declarative language that's writing a loop in SQL. I've got a whole section in Part 2 about this:What Do I Really Mean By "Cursors and Loops"? One thing that I should make clear before we go any further is just exactly what do I mean by "Cursors" and "Loops" in SQL? Technically, anything in SQL that serializes a data stream and can keep positional context is a cursor. However, when I say "cursors are bad" I do not mean this more general designation of cursors, such as client-side cursors, internal cursors, implicit cursors, pseudo-cursors, etc. I mean explicit Transact-SQL server-side cursors. These are the kind that are explicitly written in procedures and that use the CURSOR datatype. You may have noticed that I usually capitalize "Cursor" and this is to intentionally indicate these explicit Cursors. In the event that I should ever be talking about the more general concept or types of cursors, then I use the lower case form.
Loops also exist at all levels of SQL Server and any processing of a set by a processor must at some level come down to one or more loops. However, my concern is with explicit loops, particularly the WHILE statement in SQL. Implicit loops and cursors are of no real concern in this for two reasons. First, they are implemented by SQL Server below the statement level and are thus as efficient as anything else in SQL Server. And secondly, their use by SQL Server is technically a procedural implementation of the declarative SQL commands that we have given it, which is entirely what is expected of a declarative programming environment. So I am only arguing for dropping explicit Cursors and While loops.
Finally, you say:
I'm being a bit pedantic here, I know, but I,m doing it because think your over-strong denial of the usefulness of loops detracts from your message.
Now if instead of loops you had said "while loops" that would be a different story, of course (I use those too sometimes, in SQL 2000, but only because 8000 isn't big enough no need in SQL 2005 and onwards). I accept your criticism on this point. "While loops" is what I intended and what I should have said. I will try to be more conscientious about this in the future (Jeff Moden actually pokes me about this too).
-- RBarryYoung, (302)375-0451 blog: MovingSQL.com, Twitter: @RBarryYoung Proactive Performance Solutions, Inc. "Performance is our middle name."
|
|
|
|
|
SSCrazy Eights
        
Group: General Forum Members
Last Login: Wednesday, March 17, 2010 11:21 AM
Points: 9,104,
Visits: 8,528
|
|
|
|
|
|
SSC Rookie
      
Group: General Forum Members
Last Login: Friday, March 12, 2010 2:01 PM
Points: 26,
Visits: 80
|
|
... declarative in his sense means specifying the result you want (chocolate chip cookies) rather than specifying a method of achieving it (make the mix, bake it). You've fallen into the trap of saying that "the desired result is cookies with chocolate chips" means the same as "make a cookie mix and bake it to get cookies with chocolate chips" but they are clearly different: the former leaves you the choice between buying a bag of cookies, cooking your own cookies, or commissioning someone else to cook them for you (and a few other methods, of course); the latter requires you to cook them, not buy them or get someone else to make them. So the former is not at all procedural - how can it be, when it doesn't constrain the procedure for achieving the end result, it only constrains the end result?
A very clear way of going back to basics. That is nice too.
|
|
|
|