Jump to content

antonch

Administrators
  • Posts

    1030
  • Joined

  • Last visited

  • Days Won

    7

Blog Entries posted by antonch

  1. antonch
    Αφορμή για το post αυτό μου έδωσε αυτό το post, Protect object from accidental deletion.
    Για να κάνω κάτι τέτοιο στον SQL Server το μόνο που χρειάζεται να κάνω είναι να φτιάξω ένα απλό DML Trigger.
    Με το παρακάτω script γίνεται αυτό που θέλω και έτσι δεν πρόκειτε ποτέ να σβήσω μια βάση. Αν θελήσω να σβήσω μια βάση θα πρέπει πρώτα να κάνω disable τον trigger να κάνω την διαγραφή μου και μετά να ενεργοποίησω ξανά αυτόν.
    CREATE TRIGGER NoDeleteDB ON ALL SERVER FOR DROP_DATABASE
    AS
    ROLLBACK
    GO
    DISABLE TRIGGER NoDeleteDB ON ALL SERVER
    ENABLE TRIGGER NoDeleteDB ON ALL SERVER
  2. antonch
    Είχα σκοπό να τα φτιάξω κάτι σχετικό, αλλά ψάχνοντας για κάτι άλλο, έπεσα επάνω τους. Σας δίνω τα links ώστε να τα δείτε.
    Installation of a Single Node Failover Cluster in SQL Server 2008
    Add a Node to an Existing Failover Cluster in SQL Server 2008
    Remove a Passive Node from an Existing Failover Cluster in SQL Server 2008
    Remove the Active Node from an Existing Failover Cluster in SQL Server 2008
  3. antonch
    Σημέρα ένας αγαπητός συνάδελφος έρχεται στο γραφείο μου και μου κάνει την εξής ερώτηση:
    «Υπάρχει κανένας τρόπος με τον οποίο μπορώ να δω το μέγεθος των πραγματικών δεδομένων που έχουν αποθηκευτεί στην βάση μου σε ένα πεδίο τύπου image;»
    Σίγουρα η πρώτη σκέψη όλων μας θα πάει στην LEN(), αλλά αυτή όμως δεν παίζει με πεδία τύπου image, text, ntext.
    Αντί για αυτή μπορούμε να χρησιμοποιήσουμε την DATALENGTH() η οποία επιστρέφει το μέγεθος σε bytes και η οποία φυσικά μπορεί να χρησιμοποιηθεί και για όλα τα άλλα data types του SQL Server.
    Ένα παράδειγμα
    Έστω ότι έχω τον πίνακα Α
    CREATE TABLE A ( ID INT PRIMARY KEY NOT NULL, PHOTO IMAGE )
    Μπορώ να διαβάζω το πραγματικό αποθηκευμένο μέγεθος στο πεδίο PHOTO με ένα απλό query
    SELECT ID, DATALENGTH(PHOTO) SizeInBytes, DATALENGTH(PHOTO)/1024 SizeInKB FROM A
    Αυτά για την ώρα, καλή σας ημέρα και καλό SQL Server programming


  4. antonch
    Όταν δημιουργήτε ένα report το οποίο έχει μέσα του images και θέλετε να έχετε μικρό μέγεθος αρχείου όταν το κάνετε export σε PDF, φροντίστε αυτές να είναι σε jpeg format.
    Οτιδήποτε άλλο τα reporting services το μεταφράζουν σε BMP και αυτό έχει σαν αποτέλεσμα να μεγαλώνει δραματικά το μέγεθος του αρχείο ειδικότερα αν έχετε μεγάλο αριθμό από εικόνες ή φωτογραφίες.
  5. antonch
    Ψάχνοντας μέσα στα αρχεία μου σήμερα για κάτι άλλο ανακάλυψα μια λίστα την οποία είχα κάνει στο παρελθόν και η οποία δείχνει κάτι το οποίο είναι λίγο περίεργο στον SQL Server.
    Αυτό που είναι περιέργο είναι ότι σε όλα τα άλλα προιόντα της Microsoft όταν βάζει κάποιο service pack ή cummulative update μπορείς εύκολα μετά να καταλάβεις τι έχεις κάνει install πηγαίνοντας στο about ή δίνοντας μια εντολή.
    Στον SQL Server δεν είναι όμως τόσο απλά τα πράγματα. Μια εύκολη λύση είναι να εκτελέσεις το SELECT @@version το οποίο σου δίνει πληροφορίες όμως δεν λέει τόσο ξεκάθαρα τα πράγματα. Το μόνο που στην ουσία σου δίνει ακριβή πληροφορία είναι το Version number και εσύ πρέπει από αυτό να καταλάβεις τι έχεις εγκαταστήσει.
    Χωρίς την παρακάτω λίστα είσαι χαμένος από χέρι και ομολογώ ότι είχα καιρό να την ανανεώσω όμως αυτό ήταν το εύκολο μέρος. Θα συνεχίσω να την ενημερώνω στο παρόν post. Η λίστα μου περιέχει την έκδοση και το τι αυτή περιέχει και διορθώνει
    Version
    Περιέχει/Διορθώνει
    SQL Server 2008 R2

    10.5.1720.0
    SQL Server 2008 R2 CU2
    10.5.1702.0
    SQL Server 2008 R2 CU1
    10.5.1600.1
    SQL Server 2008 R2 RTM
    SQL Server 2008

    10.00.2775
    SQL Server 2008 SP1 CU8
    10.00.2766
    SQL Server 2008 SP1 CU7
    10.00.2757
    SQL Server 2008 SP1 CU6
    10.00.2746
    SQL Server 2008 SP1 CU5
    10.00.2734
    SQL Server 2008 SP1 CU4
    10.00.2723
    SQL Server 2008 SP1 CU3
    10.00.2714
    SQL Server 2008 SP1 CU2
    10.00.2710
    SQL Server 2008 SP1 CU1
    10.00.2531
    SQL Server 2008 SP1
    10.00.1835
    SQL Server 2008 RTM CU10
    10.00.1828
    SQL Server 2008 RTM CU9
    10.00.1823
    SQL Server 2008 RTM CU8
    10.00.1818
    SQL Server 2008 RTM CU7
    10.00.1812
    SQL Server 2008 RTM CU6
    10.00.1806
    SQL Server 2008 RTM CU5
    10.00.1798
    SQL Server 2008 RTM CU4
    10.00.1787
    SQL Server 2008 RTM CU3
    10.00.1779
    SQL Server 2008 RTM CU2
    10.00.1763
    SQL Server 2008 RTM CU1
    10.00.1600
    SQL Server 2008 RTM
    SQL Server 2005

    9.00.4305
    SQL Server 2005 SP3 CU10
    9.00.4294
    SQL Server 2005 SP3 CU9
    9.00.4285
    SQL Server 2005 SP3 CU8
    9.00.4273
    SQL Server 2005 SP3 CU7
    9.00.4266
    SQL Server 2005 SP3 CU6
    9.00.4230
    SQL Server 2005 SP3 CU5
    9.00.4226
    SQL Server 2005 SP3 CU4
    9.00.4220
    SQL Server 2005 SP3 CU3
    9.00.4211
    SQL Server 2005 SP3 CU2
    9.00.4207
    SQL Server 2005 SP3 CU1
    9.00.4053
    SQL Server 2005 SP3 GDR
    9.00.4035
    SQL Server 2005 SP3
    9.00.3356
    SQL Server 2005 SP2 CU17
    9.00.3355
    SQL Server 2005 SP2 CU16
    9.00.3330
    SQL Server 2005 SP2 CU15
    9.00.3328
    SQL Server 2005 SP2 CU14
    9.00.3225
    SQL Server 2005 SP2 CU13
    9.00.3315
    SQL Server 2005 SP2 CU12
    9.00.3310
    SQL Server 2005 Security Update
    9.00.3301
    SQL Server 2005 SP2 CU11
    9.00.3294
    SQL Server 2005 SP2 CU10
    9.00.3282
    SQL Server 2005 SP2 CU9
    9.00.3257
    SQL Server 2005 SP2 CU8
    9.00.3239
    SQL Server 2005 SP2 CU7
    9.00.3233
    SQL Server 2005 QFE Security Update
    9.00.3228
    SQL Server 2005 SP2 CU6
    9.00.3215
    SQL Server 2005 SP2 CU5
    9.00.3200
    SQL Server 2005 SP2 CU4
    9.00.3186
    SQL Server 2005 SP2 CU3
    9.00.3175
    SQL Server 2005 SP2 CU2
    9.00.3161
    SQL Server 2005 SP2 CU1
    9.00.3152
    SQL Server 2005 SP2 Hotfix
    9.00.3077
    SQL Server 2005 Security Update
    9.00.3054
    KB934458
    9.00.3042.01
    SQL Server 2005 "SP2a"
    9.00.3042
    SQL Server 2005 SP2
    9.00.2047
    SQL Server 2005 SP1
    9.00.1399
    SQL Server 2005 RTM
    SQL Server 2000

    8.00.2039
    SQL Server 2000 SP4
    8.00.760
    SQL Server 2000 SP3
    8.00.534
    SQL Server 2000 SP2
    8.00.384
    SQL Server 2000 SP1
    8.00.194
    SQL Server 2000 RTM
    SQL Server 7

    7.00.1063
    SQL Server 7.0 SP4
    7.00.961
    SQL Server 7.0 SP3
    7.00.842
    SQL Server 7.0 SP2
    7.00.699
    SQL Server 7.0 SP1
    7.00.623
    SQL Server 7.0 RTM
    SQL Server 6.5

    6.50.416
    SQL Server 6.5 SP5a
    6.50.415
    SQL Server 6.5 SP5
    6.50.281
    SQL Server 6.5 SP4
    6.50.258
    SQL Server 6.5 SP3
    6.50.240
    SQL Server 6.5 SP2
    6.50.213
    SQL Server 6.5 SP1
    6.50.201
    SQL Server 6.5 RTM
  6. antonch
    SSMS Tools Pack είναι ένα add-in για τον Microsoft SQL Server Management Studio (SSMS) 2005, 2008, 2008 R2 αλλά και για τις Express versions. Τα έχει φτιάξει ένας SQL Server MVP o Mladen Prajdic και τα μοιράσει δωρεάν αλλά μπορείς να αφήσεις κάτι σε αυτόν για την προσπάθεια του
    Περιέχουν αρκετά ωραία πραγματάκια που σε μερικούς λοίπουν από το SSMS όπως:
    SQL Snippets Window Connection Coloring Query Execution History and Current Window History Format SQL Search Table, View or Database Data Copy execution plan bitmaps to clipboard or file Search Results in Grid Mode Generate Insert statements from resultsets, tables or database Regions and Debug sections Running custom scripts from Object Explorer CRUD stored procedure generation New query template General options Για να τα κατεβάζετε επισκευτείτε την παρακάτω σελίδα http://www.ssmstoolspack.com/Download
  7. antonch
    Γνωρίζοντας ότι μπορεί το παρόν post μου να μην είναι ενδιαφέρον ή να προσφέρει μια γνώση που δεν έχετε, εντούτοις το γράφω διότι πρέπει κάποια πράγματα να λέγονται όπως είναι και να μην υπάρχει μαύρες τρύπες ή διαφορετικές ερμηνείες, που δυστυχώς άκουσα σήμερα.

    Τι είναι λοιπόν ένα transaction;

    Είστε σε μια εκκλησία και βλέπετε ένα ζευγάρι να παντρεύεται. Όταν τελειώσει το μυστήριο του γάμου δεν υπάρχει κανένας που να αμφιβάλλει για το status του ζευγαριού αυτού. ΕΙΝΑΙ ΠΑΝΤΡΕΜΕΝΟΙ. Εάν όμως κατά την διάρκεια του μυστήριου συμβεί κάτι πχ η νύφη το σκάσει πάλι δεν υπάρχει καμία αμφιβολία για το status τους. ΔΕΝ ΕΙΝΑΙ ΠΑΝΤΡΕΜΕΝΟΙ.

    Αυτό στην ουσία είναι και ένα transaction αγαπητές κυρίες και αγαπητοί κύριοι. Τίποτα περισσότερο τίποτα λιγότερο. Οι σύμμαχοι λένε All Or Nothing, που σημαίνει ότι όλα θα γίνουν και θα φτάσω στο επιθυμητό status (ΕΙΝΑΙ ΠΑΝΤΡΕΜΕΝΟΙ-TRANSACTION IS COMMITTED) ή αν γίνει κάτι τότε όλα γυρνάνε στην προηγούμενη κατάσταση (ΔΕΝ ΕΙΝΑΙ ΠΑΝΤΡΕΜΕΝΟΙ – TRANSACTION ROLLBACKED)

    Ένα transaction υλοποίει – διέπεται από τα ACID properties που είναι τα αρχικό των λέξεων Atomicity – Consistency – Isolation – Durability.

    Atomicity σημαίνει ότι κάθε transaction πρέπει να είναι μια αυτόνομη εργασία που είτε θα γίνουν όλα όσα αυτή ζητάει να γίνουν είτε δεν θα γίνει τίποτα.

    Consistency σημαίνει ότι με την ολοκλήρωση του transaction όλα θα είναι σε μια consistent κατάσταση (είναι παντρεμένοι ή δεν είναι παντρεμένοι). Ενδιάμεσες καταστάσεις δεν υπάρχουν. Δεν υπάρχει ολίγο παντρεμένοι ή ολίγο δεν είναι παντρεμένοι.

    Isolation σημαίνει ότι οι αλλαγές που ζητάει ένα transaction να γίνουν πρέπει να είναι απομονωμένες από τις αλλαγές που κάποια άλλα transaction που εκτελούνται ταυτόχρονα κάνουν. Δηλαδή εάν για παράδειγμα κάποιος από το ζευγάρι που παντρεύεται είναι ήδη παντρεμένο το δικό μας transaction δεν θα προχωρήσει. Ξέρω τι θα ακούσω τώρα για τα ζευγάρια που είναι δίγαμα αλλά αυτό διώκεται ποινικά ξέρετε, έτσι και εδώ υπάρχουν νόμοι και κανόνες που ευτυχώς δεν παραβιάζονται. Επίσης για να προχωρήσει το δικό μας transaction όταν κάποιο ή κάποια άλλα έχουν ξεκινήσει θα πρέπει αυτά να τελειώσουν και να αφήσουν τα δεδομένα που και εμείς θέλουμε να πειράξουμε σε μια ξεκάθαρη κατάσταση.

    Durability σημαίνει ότι αφού το transaction μας έχει ολοκληρωθεί αυτό παραμένει ακόμα και αν το σύστημα μας έχει failure.

    Για να επιτευχθούν όλα τα παραπάνω υπάρχουν τα locks τα οποία έρχονται να τηρήσουν τους κανόνες που είπαμε, αλλά για αυτά σε άλλο post.

    Autocommit Transactions ή Implicit Transactions

    Στον SQL Server έχω τα Autocommit Transactions ή Implicit Transactions που είναι και η default συμπεριφορά για κάθε sql statement που εκτελείται. Δηλαδή εκτελώ ένα insert statement αυτό θα είναι committed εφόσον δεν υπάρχει κάποιο λάθος, ενώ αν παρουσιαστεί σφάλμα αυτό είναι rollbacked.

    Για όσους θέλουν να απενεργοποιήσουν την παραπάνω συμπεριφορά του SQL Server γιατί τους φαίνεται ότι δεν είναι σωστή (επειδή έτσι νομίζουν γιατί το έχουν δει αλλού) υπάρχει η δυνατότητα με την εφαρμογή του IMPLICIT_TRANSACTION setting π.χ
    SET IMPLICIT_TRANSACTIONS ONINSERT / UPDATE / DELETE
    COMMIT / ROLLBACK







    Explicit Transactions

    Εάν θέλεις να έχεις δικά σου ελεγχόμενα transactions τότε θα πρέπει να ξεκινήσεις ένα δικό όπως στο παράδειγμα που ακολουθεί
    BEGIN TRAN….
    COMMIT / ROLLBACK
    Βέβαια θα πρέπει να είσαι προετοιμασμένος ώστε αν συμβεί κάτι να κάνεις rollback. Δεν θα σας κουράσω δείχνοντας σας πως αυτό γίνονταν πριν τον SQL Server 2005, θα σας δείξω πως γίνεται από τον 2005 και μετά που είναι και αρκετά πιο δομημένος τρόπος γραφής BEGIN TRY BEGIN TRAN
    ….
    COMMIT
    END TRY
    BEGIN CATCH
    ROLLBACK
    SELECT ERROR_NUMBER(), ERROR_MESSAGE()
    END CATCH



    Το θέμα φυσικά δεν εξαντλείτε εδώ είναι μεγάλο και θα επανέλθω σύντομα με ένα άλλο post που θα πηγαίνει περισσότερο σε βάθος.
  8. antonch
    Σε συνέχεια από το PART I.
    Report Server Databases
    Στα SSRS έχουμε δύο databases τις ReportServer και ReportServerTempDB.
    ReportServer Database
    Σε αυτή την βάση αποθηκεύονται τα παρακάτω
    SSRS configuration Report definitions Report metadata Report history Cache policies Snapshots Resources Security settings Encrypted data Scheduling and Delivery Data Extension information Όπως είναι εύκολα κατανοητό η βάση αυτή είναι και η καρδία των SSRS και φυσικά η απώλεια της σημαίνει πολλά. Για αυτό το λόγο και της συμπεριφερόμαστε όπως σε όλες τις βάσεις παραγωγής, πχ παίρνουμε καθημερινό backup.
    Επίσης θα πρέπει να τονίσω ότι μπορώ να έχω άμεση πρόσβαση στα δεδομένα των πινάκων και φυσικά να αλλοιώσω αυτά. Αυτό όμως δεν είναι recommended αλλά ούτε και supported από την Microsoft. Επίσης θα πρέπει να τονισθεί ότι υπάρχει πάντα το ενδεχόμενο με κάποιο CU ή SP η δομή της βάσης να αλλάξει.
    ReportServerTempDB Database
    Αυτή η βάση είναι υπεύθυνη για την αποθήκευση των ενδιάμεσων διαδικασιών όπως των cached reports , sessions και execution data.
    Σε αντίθεση με την TempDB του SQL Server τα δεδομένα σε αυτή την βάση παραμένουν όταν γίνεται restart είτε ο SQL Server είτε τα SSRS. Σε τακτά χρονικά διαστήματα γίνεται διαγραφή των expired και orphan data.
    Αν και μπορούμε να σβήσουμε όλα τα δεδομένα μέσα από αυτή καλό είναι να γίνει αυτό. Αν και το μόνο που μπορεί να μας συμβεί είναι οι χρήστε που είναι σε διαδικασία να δούνε ένα report θα πάρουν μήνυμα ότι δεν μπορούν να διαβάσουν τον session state (rsExecutionNotFound). Σε αυτή την περίπτωση ο χρήστης θα πρέπει να ξαναεκτελέσει το report.
    Αλλαγή θέσης των Temporary Snapshots
    Εάν κάποιος θέλει να αλλάξει τον τρόπο που temporary snapshots αποθηκεύονται και αντί για την βάση να αποθηκεύονται σε directory θα πρέπει να ακολουθήσει τα επόμενα βήματα
    Να αλλάξει στο rsreportserver.config το WebServiceUseFileShareStorage και το WindowsServiceUseFileShareStorage σε True. Να ορίζει το path που θέλει αυτά να αποθηκεύονται στο FileShareStorageLocation. Υπάρχει βέβαια default value και είναι η C:\Program Files\Microsoft SQL Server\MSES10.MSSQLSERVER\Reporting Services\RSTempFiles. Τέλος θα πρέπει να επισημάνω ότι δεν χρειάζεται οι βάσεις αυτές να είναι στην ίδια μηχανή που έχω στήσει τα SSRS αλλά σε έναν άλλο SQL Server.
  9. antonch
    Πριν από λίγο καιρό στο SQL Server Magazine διάβασα το παρακάτω το οποίο είναι αρκετά ενδιαφέρον μιας και την απάντηση την έχει δώσει ένας άνθρωπος που τον έχει φτίαξει ο Paul Randal, απολαύστε το
    Q: I’ve been wondering about the algorithm for generating log sequence numbers for transaction log records and I’m concerned that with a high enough workload it may be possible to run out of log sequence numbers. What happens in that case?
    A: There’s no need to worry as for all practical purposes it is not possible to run out of log sequence numbers.
    As a bit of background, a log sequence number is a three-part number used to uniquely identify a transaction log record – constructed from the sequence number of the virtual log file (VLF) containing the log record; the log block number within the virtual log file; the log record number within the log block.
    This isn’t really important, but what is important is that the VLF sequence number is a 64-bit number. Whenever a VLF is reused in the transaction log, the VLF sequence is increased by 1. So let’s do a little math…
    Imagine a transaction log with 65536 VLFs, each one a quarter megabyte in size (not a nonsensical situation, depending on how your transaction log is being managed – for more details on this and on transaction log internals, see Importance of proper transaction log size management). Each time the log is completely used and wraps around to the start, the VLF sequence number will increase by 65536, which is 2 to-the-power 16 (2^16).
    A 64-bit number can support 2^64 values. To be able to exhaust the 2^64 possible VLF sequence numbers, our example transaction log would have to wrap 2^64 / 2^16 = 2^48 times. That’s a lot of log wrapping. But how much transaction log does that equate to?
    Our example log is 65536 x 1/4MB in size, which is 16GB. To wrap that log 2^48 times, you’d need to generate 2^48 x 16GB of transaction log. Which equates to 4 billion petabytes (a petabyte = 1024 terabytes) of transaction log – quite an undertaking!
    Even being able to write that log out to an SSD capable of a sustained 600 MB/s, it would take 4 billion petabytes / 600 megabytes = approximately 240 million years to generate 4 billion petabytes of transaction log.
    As you can clearly see – no-one’s in any danger of running out of log sequence numbers!
  10. antonch
    Ένα απίστευτο video έχει αναρτηθεί εδώ, το οποίο με έκανε να γελάσω αρκετά σήμερα το βράδυ.
    Ελπίζω να κάνει και εσάς
  11. antonch
    Αν και το θέμα το έχουμε ξανασυζητήσει και αναλύσει στο παρελθόν εντούτοις πάντα είναι επίκαιρο και πάντα έχει παραλλαγές.


    Σήμερα ήρθα αντιμέτωπος με μία τέτοια παραλλαγή.


    Φίλος και συνεργάτης την ώρα που ήμουν στο δρόμο για το γραφείο ( 7:00 πμ ) με παίρνει στον τηλέφωνο και μου λέει.


    «Έχω μια βάση που τα 250ΜΒ είναι το data file και τα 93GB το log. Είναι από το ERP ενός πελάτη μου το οποίο θέλω να πάρω backup και να το δώσω στην εταιρεία ώστε να κάνουν κάποιους ελέγχους σε ένα θέμα που έχει προκύψει με αυτό και δεν μπορώ να το στείλω γιατί βγαίνει ένα μεγάλο μέγεθος στο backup. Έχω δει το άρθρο σου για τον Θαυμαστό κόσμο του Transaction Log και θέλω να μειώσω το log file ώστε να μην είναι τόσο μεγάλο μιας και στην πραγματικότητα δεν το έχω ανάγκη.»


    Του απαντώ ΟΚ θα σε βοηθήσω, θα σε πάρω τηλέφωνο μόλις πάω στο γραφείο.


    «Όχι τώρα θέλω» 


    Και έτσι αρχίζουμε τηλεφωνική διαδικασία μείωσης μεγέθους του log.


    Τον ρωτάω εάν έχει πρόσφατο full backup και t-log backup. Η απάντηση του ήταν ότι είχε μόνο full, οπότε ξεκινήσαμε να παίρνουμε t-log backup ώστε να γίνει truncate το log.


    Με τη ολοκλήρωση του backup (t-log) τον οδήγησα να πάει μέσω του SSMS να κάνει Shrink File στο transaction log (right click on database Tasks Shrink…), και στην συνέχεια να επιλέξει την 1η επιλογή (αυτή που λέει ότι θα δει το υπάρχον μέγεθος και τα πραγματικά δεδομένα και θα βρει το optimal).


    Πραγματικά μετά από την εκτέλεση υπήρχε μια μείωση του μεγέθους του log αρχείου αλλά η διαφορά ήταν αρκετά μικρή από τα 93 GB πέσαμε στα 90GB.


    Αυτό με έβαλε σε σκέψεις και του είπα να μου πει τον τρόπο με τον οποίο μεγαλώνει το transaction log όταν γεμίζει. Η απάντηση ήταν αυτή που υποψιαζόμουν γίνονταν expand κατά 10%. Αυτό όπως έχω πει επανειλημμένος δημιουργεί virtual logs τα οποία επειδή δεν είναι ισόποσα δεν μπορούν να συγχρονιστούν και έτσι φυσικά μεγαλώνει και το log.


    Για να επιβεβαιώσω  ότι δεν  χρησιμοποιούνται όλα αυτά τα GBs του λέω να εκτελέσει την εντολή DBCC SQLPERF(LOGSPACE) και να μου πει το ποσοστό το οποίο είναι used. Πραγματικά δεν ήταν μεγάλο (18%).


    Έτσι μιας και ήμουν στο αυτοκίνητο και οδηγούσα και μιας και ο φίλος  δεν είναι sqlman επέλεξα ένα εύκολο τρόπο για λύσω άμεσα το πρόβλημα.


    Του είπα και γύρισε μέσα από τoν SSMS την βάση σε simple recovery model, και να πάει να κάνει ξανά shrink file το log. Με μία μικρή διαφορά, αυτή την φορά του είπα να πάει στην επιλογή όπου ορίζουμε το επιθυμητό μέγεθος και του είπα να δώσει 250ΜΒ. O λόγος που του το είπα αυτό είναι για να γλυτώσει IO κατά την διάρκεια των επόμενων expantions του log.


    Έτσι έχουμε μια ακόμα ιστορία που αποδεικνύει ότι πρέπει να παίρνουμε KAI transaction log backup όταν έχουμε full recovery model στην database. Επίσης έχουμε και τον τρόπο με τον οποίο μπορούμε να μικρύνουμε το μέγεθος του log file.

  12. antonch
    Είναι γνωστή η λατρεία μου για ποστερς και ειδικά τέτοιου είδους όπως αυτό εδώ

    Απλά θέλεις χώρο και ploter για να τα τυπώσεις.... []

    Όπως και να έχει όμως είναι αυτό που πρέπει να μελετήσει κάποιος που ασχολήται με τον SQL Server 2008R2 καθώς θα μπουν πολλά πράγματα στο κεφάλι του σε σειρά.

    Enjoy it!
  13. antonch
    Την προηγούμενη εβδομάδα κατά την διάρκεια του 4ο DevDays 2010 μου δώθηκε η ευκαιρία να μιλήσω για πρώτη φορά για τον νέο SQL Server “Denali”
    Το video (κλικ στην εικόνα παρακάτω) είναι ήδη διαθέσιμο και μπορείτε να το δείτε όσοι δεν μπόρεσαν να είναι παρόντες

  14. antonch
    Όπως γνωρίζεται από την έκδοση του SQL Server 2005 και μετά υπάρχουν τα dynamic management object. 
    Είναι αυτά τα οποία τα βρίσκετε σε κάθε database όταν κάνε expand στον SSMS > Database > Views > System Views .
    Αυτά έχουν έρθει να κάνουν την ζωή μας ευκολότερη και αρκετά από αυτά έχουν σαν σκοπό να καταργήσουν κάποια DBCC statements.
    Όπως και να έχει είναι αρκετά χρήσιμα διότι έτσι αντλούμε ότι πληροφορίες θέλουμε σχετικά με την βάση μας ή το SQL Server.
    Αυτό όμως που τα κάνει ακόμα ομορφότερα είναι ότι είναι εμπλουτισμένα με περισσότερες πληροφορίες που τα κάνουν ακόμα ποιο χρηστικά.
    Ένα από αυτά τα χαρακτηριστικά είναι μέσα σε αυτά υπάρχουν columns τα οποία τελειώνουν με _desc.
    Τα columns αυτά τα λέμε friendly name columns και είναι πάντα ζευγάρι με ένα άλλο column το οποίο δεν έχει στο τέλος το _desc.
    π.χ. Έστω ότι θέλεις να δεις το Recovery Model σε όλες σου τις databases που έχει στον SQL Server σου. Αυτό είναι εύκολο να το κάνεις αρκεί να εκτελέσεις το παρακάτω query.

    SELECT name, recovery_model FROM sys.databases
     
    Αυτό θα σου επιστρέψει ένα αποτέλεσμα τις μορφής
     








    name




    recovery_model





    master




    3





    tempdb




    3





    model




    1





    msdb




    3





    demo




    2





    ...




    ...

     
    Για αυτούς που ασχολούνται χρόνια με τον SQL Server αυτό είναι αρκετό μιας και ξέρουν τι σημαίνει η τιμή  1,2,3 στο recovery model.
    Τι γίνεται όμως με αυτούς που δεν έχουν ασχοληθεί αρκετά μαζί του.
    Οι τιμές 1,2,3 δεν του λένε πολλά πράγματα.
    Για αυτούς αλλά και για τους έμπειρους υπάρχουν οι columns για τις οποίες μιλάμε.
    Έτσι εύκολα πλέον αν στο παραπάνω query προσθέσουμε την friendly column όπως παρακάτω
     
    SELECT name, recovery_model, recovery_model_desc  FROM sys.databases
     
    Το οποίο θα μου γυρίσει το εξής αποτέλεσμα το οποίο φυσικά είναι και ποιο κατανοητό.









    name




    recovery_model




    recovery_model_desc





    master




    3




    SIMPLE





    tempdb




    3




    SIMPLE





    model




    1




    FULL





    msdb




    3




    SIMPLE





    demo




    2




    BULK_LOGGED





    ...




    ...




     

     
    Εδώ τώρα έρχεται το ερώτημα το οποίο μου τέθηκε σήμερα και αποτέλεσε την αφορμή για το post αυτό.

    «Και γιατί να έχω και τις δυο κολώνες αυτές, αφού με την κολώνα που έχω την περιγραφή κάνω μια χαρά την δουλειά μου;»

    Η απάντηση είναι απλή.
     
    Υπάρχουν συνάδελφοι που έχουν κάθε φορά διαφορετικές ανάγκες. Για παράδειγμα εσωτερικά στην Microsoft η ομάδα ανάπτυξης όταν υλοποιεί τα εσωτερικά interfaces του SQL Server θέλει να κάνει bind σε ποιο μικρά σε μέγεθος columns όπως το recovery_model το οποίο είναι ένας integer. Επίσης πολλοί από αυτούς που φτιάχνουν καλούδια στον SQL Server ή μέσα από τις εφαρμογές τους θέλουν να αντλήσουν system level πληροφορίες τους είναι ποιο εύκολο να χρησιμοποιήσουν αυτές τις κολώνες.
    Υπάρχουν όμως και οι DBAs που θέλουν με το adhoc query τους να δουν και την ερμηνεία της κολώνας έτσι χρησιμοποιούν το πεδίο με το _desc.
     
    Καλή Χρονιά σε όλες και όλους
     

     
  15. antonch
    Πρόσφατα ένας αξιόλογος και σεβάσμιος MVP o Glenn Berry (blog|twitter) μας ανακοίνωσε ότι έχει κάνει update την βιβλιοθήκη του με τα queries τα οποία χρησιμοποιεί για να διαγνώσει προβλήματα στον SQL Server.
    Επειδή αρκετοί με ρωτάτε για το πως να διαγνώσετε τα προβλήματα που σας εμφανίζονται νομίζω ότι είναι μια καλή αρχή να δείτε αυτά και να εξοικιωθείτε μαζί του. Μπορείτε να τα κατεβάσετε από εδώ.
    Παρέχουν αρκετά καλή πληροφορία και σε συνδιασμό ότι αυτά θα τα βάλεις σε ένα Excel (και αυτό το δίνει ο Glenn ) είναι ένα χρήσιμο εργαλείο για κάθε DBA.
    Προσωπικά τα έχω ήδη εντάξει στην φαρέτρα μου με τα διαγνωστικά μου εργαλεία για τον SQL Server.΄
    Για οποιαδήποτε ερώτηση σας με αυτά είμαι στην διάθεση σας.
  16. antonch
    Σαν developers αρκετές φορές ερχόμαστε αντιμέτωποι με προβλήματα που πρέπει να λύσουμε μέσα σε σύντομο χρονικό διάστημα. Τις περισσότερες φορές η λύση που επιλέγουμε για να το λύσουμε είναι αυτή που ξέρουμε καλύτερα, την έχουν χρησιμοποιήσει αρκετές φορές, την εμπιστευόμαστε περισσότερο ή αυτή ξέρουμε μόνο.
    Κάποιες φορές αυτή είναι ιδανική, καλή, μέτρια ή άστα να πάνε…
    Ας έρθουμε όμως στο προκείμενο…
    Πριν μερικές μέρες είχα να αντιμετωπίσω ένα θέμα το οποίο πάντα όταν ανακύπτει προκαλεί πολλά σχόλια, αρνητικά κυρίως, από συναδέλφους που βλέπουν το SQL Server σαν ένα μέσω αποθήκευσης και μόνο των δεδομένων, αυτό που εγώ λέω κουβά.
    Το πρόβλημα είναι το εξής «Έχω ένα ή περισσότερους πίνακες που θέλω να τους ρωτήσω με πολλαπλά φίλτρα τα οποία άλλες φορές θα έχουν τιμή και άλλες όχι. Με ποιο απλά λόγια αν το φίλτρο έχει τιμή τότε θέλω να είναι στο WHERE αλλιώς όχι».
    Αυτό όταν το ακούς ή το αντιμετωπίζεις, άμεσα το μυαλό σου πηγαίνει στο «θέλω δυναμικά να κτίζω το WHERE clause στο SELECT που θα κάνω».
    Αυτό σημαίνει αρκετά πράγματα τα οποία θα ήταν κουτό από μέρος μου να κάτσω να τα γράψω μιας και ο Erland Sommarskog (blog), MVP και αυτός στον SQL Server, έχει ήδη γράψει ένα καταπληκτικό post με τίτλο «The Curse and Blessings of Dynamic SQL», το οποίο και εγώ πριν αρχίσω την συγγραφή αυτού του post δεν γνώριζα την ύπαρξη του. Αλλά ευτυχώς είχα την προνοητικότητα να ρωτήσω τους άλλους MVPs αν κάποιος έχει γράψει κάτι για αυτό ώστε να εστιάσω την προσοχή μου σε αυτό που θέλω να αναλύσω χωρίς να γράψω όλη την ιστορία από την αρχή.Thanks Er!.
    Ας πάρουμε για παράδειγμα το εξής:
    Θέλω να έχω μια stored procedure που να παίρνει σαν παραμέτρους πεδία του πίνακα Customers και του πίνακα Orders από την Northwind και ανάλογα να κάνει αναζήτηση με το τι τιμές ή όχι έχω δώσει σε αυτές και να μου επιστρέφει το επιθυμητό αποτέλεσμα που στην περίπτωση του παραδείγματος μας θα είναι οι παραγγελίες ανά πελάτη.
    Αυτό σημαίνει ότι η συγκεκριμένη stored pocedure θα πρέπει να έχει την δυνατότητα να μην πάρει τιμές σε καμία από αυτές άρα θα πρέπει αυτές να είναι αρχικοποιημένες με μια τιμή που στην περίπτωση μας η τιμή αυτή θα είναι null. Έτσι ένα πιθανό stored procedure signature θα μπορούσε να είναι το παρακάτω
    CREATE PROC spGetCustomerOrders
    @CompanyName NVARCHAR(40)=NULL,
    @Country NVARCHAR(15)=NULL,
    @City NVARCHAR(15)=NULL,
    @Region NVARCHAR(15)=NULL,
    @OrderDate_Min DATETIME=NULL,
    @OrderDate_Max DATETIME=NULL,
    @Employees NVARCHAR(100)=NULL




    Το αποτέλεσμα που θέλω να επιστρέφει είναι το εξής query


    SELECT o.OrderID,
    o.EmployeeID,
    c.CustomerID,
    c.CompanyName,
    o.OrderDate,
    c.Country,
    c.City,
    c.Region
    FROM Customers c
    INNER JOIN Orders o ON c.CustomerID=o.CustomerID

    το οποίο θέλω να έχει τα εξής φίλτρα κατά την αναζήτηση φυσικά όταν για αυτά μου έχουν δώσει τιμές αλλιώς δεν θέλω να μπλέκονται σε αυτή. Σε πλήρη ανάπτυξη τα φίλτρα μου θέλω να είναι όπως παρακάτω


    WHERE
    c.CompanyName LIKE @CompanyName + '%'
    AND
    c.Country = @Country
    AND
    c.City = @City
    AND
    c.Region = @Region
    AND
    o.OrderDate BETWEEN @OrderDate_Min AND @OrderDate_Max
    AND
    o.EmployeeID IN ()

    Αν σαν πρώτη σκέψη είχα το dynamic sql τότε μια πιθανή υλοποίηση θα ήταν η παρακάτω


    CREATE PROC spGetCustomerOrders @CompanyName NVARCHAR(40)=NULL,
    @Country NVARCHAR(15)=NULL,
    @City NVARCHAR(15)=NULL,
    @Region NVARCHAR(15)=NULL,
    @OrderDate_Min DATETIME=NULL,
    @OrderDate_Max DATETIME=NULL,
    @Employees NVARCHAR(100)=null
    AS

    SET NOCOUNT ON;

    DECLARE @select nvarchar(2000)
    DECLARE @where nvarchar(1000)

    SET @OrderDate_Min = ISNULL(@OrderDate_Min,'19000101')
    SET @OrderDate_Max = ISNULL(@OrderDate_Max,'99991231')

    IF ( @OrderDate_Min > @OrderDate_Max )
    BEGIN
    RAISERROR ('@OrderDate_Min is bigger than @OrderDate_Max',16,1)
    RETURN
    END

    SET @select = 'SELECT o.OrderID, o.EmployeeID, c.CustomerID, c.CompanyName, o.OrderDate, c.Country, c.City, c.Region FROM Customers c INNER JOIN Orders o ON c.CustomerID=o.CustomerID '

    -- ΓΙΑ ΝΑ ΕΙΜΑΙ ΑΣΦΑΛΕΙΣ ΕΔΩ ΘΑ ΠΡΈΠΕΙ ΝΑ ΕΛΕΞΩ ΓΙΑ SQL INJECTION

    SET @where = 'WHERE (o.OrderDate BETWEEN ''' + CONVERT(char(10),@OrderDate_Min,102) + ''' AND ''' + CONVERT(char(10),@OrderDate_Max,102) + ''')'
    if not @CompanyName is null SET @where += ' AND (c.CompanyName LIKE ''' + @CompanyName + '%' +''')'
    if not @Country is null SET @where += ' AND (c.Country = ''' + @Country + ''')'
    if not @City is null SET @where += ' AND (c.City = ''' + @City + ''')'
    if not @Region is null SET @where += ' AND (c.Region = ''' + @Region + ''')'
    if not @Employees is null SET @where += ' AND (o.EmployeeID IN ('+ @Employees + '))'
    SET @select += @where
    EXEC (@select)
    GO

    Και ο τρόπος εκτέλεσης της θα ήταν ο παρακάτω


    exec spGetCustomerOrders @CompanyName = 'c',
    @Country ='UK',
    @City =null,
    @Region =null,
    @OrderDate_Min =null,
    @OrderDate_Max =null,
    @Employees ='1,2,3,4'

    Ουφ κουράστηκα να γράφω και να προσέχω τα μονά quotes που ανοίγουν που κλείνουν να βάζω ακόμα ένα σε αυτά ώστε να συμπεριληφθούν στο string, α και να προσέξω για sql injection.


    Το τελευταίο θα μπορούσα εύκολα να το αποφύγω αν άλλαζα τον κτίσιμο του sql statement όπως παρακάτω


    CREATE PROC spGetCustomerOrders @CompanyName NVARCHAR(40)=NULL,
    @Country NVARCHAR(15)=NULL,
    @City NVARCHAR(15)=NULL,
    @Region NVARCHAR(15)=NULL,
    @OrderDate_Min DATETIME=NULL,
    @OrderDate_Max DATETIME=NULL,
    @Employees NVARCHAR(100)=null
    AS

    SET NOCOUNT ON;

    DECLARE @select nvarchar(2000)
    DECLARE @where nvarchar(1000)

    SET @OrderDate_Min = ISNULL(@OrderDate_Min,'19000101')
    SET @OrderDate_Max = ISNULL(@OrderDate_Max,'99991231')

    IF ( @OrderDate_Min > @OrderDate_Max )
    BEGIN
    RAISERROR ('@OrderDate_Min is bigger than @OrderDate_Max',16,1)
    RETURN
    END

    SET @select = 'SELECT o.OrderID, o.EmployeeID, c.CustomerID, c.CompanyName, o.OrderDate, c.Country, c.City, c.Region FROM Customers c INNER JOIN Orders o ON c.CustomerID=o.CustomerID '
    SET @where = 'WHERE (o.OrderDate BETWEEN @OrderDate_Min AND @OrderDate_Max)'

    if not @CompanyName is null SET @where += ' AND (c.CompanyName LIKE @CompanyName)'
    if not @Country is null SET @where += ' AND (c.Country = @Country)'
    if not @City is null SET @where += ' AND (c.City = @City )'
    if not @Region is null SET @where += ' AND (c.Region = @Region )'
    if not @Employees is null SET @where += ' AND (o.EmployeeID IN (@Employees))'
    SET @select += @where

    EXEC sp_executesql @select,N'@CompanyName NVARCHAR(40), @Country NVARCHAR(15), @City NVARCHAR(15), @Region NVARCHAR(15), @OrderDate_Min DATETIME, @OrderDate_Max DATETIME, @Employees NVARCHAR(100)', @CompanyName, @Country, @City, @Region, @OrderDate_Min, @OrderDate_Max, @Employees

    GO

    Και ο τρόπος εκτέλεσης της θα ήταν ο παρακάτω


    exec spGetCustomerOrders @CompanyName = 'c%',
    @Country ='UK',
    @City =null,
    @Region =null,
    @OrderDate_Min =null,
    @OrderDate_Max =null,
    @Employees =null

    Μήπως όμως θα μπορούσα να την γράψω αλλιώς; Χωρίς dynamic sql; Ας το δοκιμάσουμε.


    Αρχικά με ενοχλεί η παράμετρος @Employees που είναι nvarchar. Θα ήθελα να είναι array. Μα καλά θα μου πεις array σε T-SQL, τι πίνεις;


    Όντως η έννοια αυτή δεν υπάρχει σε T-SQL, όμως υπάρχουν οι πίνακες και τα table-value parameters. Έτσι φτιάχνω ένα δικό μου data type που θα είναι table data type και θα παίζει το ρόλο του array


    CREATE TYPE OrderEmployees AS TABLE (EmployeeID INT);
    GO

    Και θα αλλάξω την παράμετρο @Employees σε αυτό το table data type. Έτσι πλέον το stored procedure signature θα γίνει


    CREATE PROC spGetCustomerOrders @CompanyName NVARCHAR(40)=NULL,
    @Country NVARCHAR(15)=NULL,
    @City NVARCHAR(15)=NULL,
    @Region NVARCHAR(15)=NULL,
    @OrderDate_Min DATETIME=NULL,
    @OrderDate_Max DATETIME=NULL,
    @Employees OrderEmployees READONLY

    Για να ξέρω αν έχω rows στο @Employees table-value parameter δηλώνω την μεταβλητή @ HasEmployees σαν bit (Boolean) και την γεμίζω ανάλογα 0 δεν έχω, 1 έχω rows


    DECLARE @HasEmployees BIT
    SET @HasEmployees = CASE WHEN (SELECT COUNT(*) FROM @Employees)>0 THEN 1 ELSE 0 END

    Αρχικοποιώ και τις @OrderDate_Min, @OrderDate_Max ώστε να μπορώ να παίρνω όλα τα rows σε περίπτωση που δεν μου δώσουν τιμές


    SET @OrderDate_Min = ISNULL(@OrderDate_Min,'19000101')
    SET @OrderDate_Max = ISNULL(@OrderDate_Max,'99991231')




    Η υλοποίηση της θα μπορούσε να είναι η παρακάτω


    CREATE PROC spGetCustomerOrders @CompanyName NVARCHAR(40)=NULL,
    @Country NVARCHAR(15)=NULL,
    @City NVARCHAR(15)=NULL,
    @Region NVARCHAR(15)=NULL,
    @OrderDate_Min DATETIME=NULL,
    @OrderDate_Max DATETIME=NULL,
    @Employees OrderEmployees READONLY
    AS

    SET NOCOUNT ON;

    DECLARE @HasEmployees BIT
    SET @OrderDate_Min = ISNULL(@OrderDate_Min,'19000101')
    SET @OrderDate_Max = ISNULL(@OrderDate_Max,'99991231')
    SET @HasEmployees = CASE WHEN (SELECT COUNT(*) FROM @Employees)>0 THEN 1 ELSE 0 END

    SELECT o.OrderID, o.EmployeeID, c.CustomerID,c.CompanyName,o.OrderDate,c.Country,c.City,c.Region
    FROM Customers c
    INNER JOIN Orders o ON c.CustomerID=o.CustomerID
    WHERE
    ((c.CompanyName LIKE @CompanyName + '%') OR (@CompanyName IS NULL))
    AND
    ((c.Country = @Country) OR (@Country IS NULL))
    AND
    ((c.City = @City) OR (@City IS NULL))
    AND
    ((c.Region = @Region) OR (@Region IS NULL))
    AND
    (o.OrderDate BETWEEN @OrderDate_Min AND @OrderDate_Max )
    AND
    (CASE @HasEmployees
    WHEN 0 THEN 1
    ELSE
    CASE WHEN o.EmployeeID IN (SELECT EmployeeID FROM @Employees) THEN 1
    ELSE 0
    END
    END = 1 )
    GO

    Και η εκτέλεση αυτής


    DECLARE @e OrderEmployees
    -- Κάνω remark το insert αυτό αν θέλω να προσομοιάσω το γεγονός ότι δεν μου δίνουν τιμές στους υπαλλήλους
    INSERT INTO @e VALUES (8),(4)

    EXEC spGetCustomerOrders @CompanyName='c',
    @Country='UK',
    @City=NULL,
    @Region=NULL,
    @OrderDate_Min=NULL,
    @OrderDate_Max=NULL,
    @Employees=@e

    Το σημαντικό όμως είναι η διαφορά σε χρόνο εκτέλεσης καθώς η λύση που δεν περιέχει το dynamic sql είναι γρηγορότερη τουλάχιστον κατά 60%
  17. antonch
    Today I’m pleased to announce the availability of the SQL Server 2008 R2 Update For Developers January 2011 Update. This is a great resource for developers, trainers, consultants and evangelists who need to understand the key improvements introduced in SQL Server 2008 and SQL Server 2008 R2 from a developer perspective. It contains a rich set of presentations, demos, hands-on labs and videos that are perfect for self-paced learning or for conducting your own training. The January 2011 update includes lots of great new content and several usability improvements.
    The easiest way to get started with the training kit is to download it, install it, open default.htm and browse the kit for the content that you are most interested in. Many of the presentations and demos in the training kit include a video that you can watch to familiarize yourself with the content. When you are ready for some hands-on experience, try installing one of the demos or hands-on labs. Each of them includes a configuration wizard that simplifies installation. Check out the following sections for more on what’s new in this update.
    Ø New Content: Build Your First Microsoft BI Solution with SQL Server 2008 R2
    Ø Other Content in the Training Kit
    Ø Usability Improvements
    Ø Virtual Machine Information
    Ø What’s Next
    You can download the training kit now at the following URL:
    http://go.microsoft.com/?linkid=9710868
    This training kit is brought to you by DPE’s Data Platform Evangelism team. Please feel free to email us at [email protected] with your feedback and questions. We are particularly interested in hearing about use of this content to drive SQL Server developer adoption.
    Regards,
    Roger
    Roger Doherty | Sr. Technical Evangelist | Microsoft Corp.
  18. antonch
    Posted @ 2/20/2011 9:31 PM By Kimberly L. Tripp
    Posted in SQL Server Magazine
    Πριν μερικές μέρες είχα δημοσιεύσει ένα άρθρο “Dynamic SQL ή μήπως μπορώ και αλλιώς;”. Σήμερα διάβασα το παρακάτω άρθρο της Kimberly Trip το οποίο καλύπτει μια άλλη πτυχή την οποία δεν είχα καλύψει στο δικό μου. Και τα δύο άρθρα είναι σωστά και έρχονται να επιβεβαιώσουν ότι τίποτα μα τίποτα δεν είναι defacto στον SQL Server. Στην ουσία για μένα είναι ακόμα μια επιβεβαίωση της γνωστής απάντησης που σε αρκετές περιπτώσεις δίνω και δεν είναι άλλη από το ΕΞΑΡΤΑΤΑΙ. Τα πάντα είναι θέμα ποιότητας και ποσότητας δεδομένων.!!!
     
    Question: This is a follow-up question to the Q&A post: Statistics, literals, recompilation… confusion! posted last week.
    Would it actually be better to use OPTION(RECOMPILE), rather than dynamic SQL (DSE), as in reality, both options are likely to re-compile each time, and forcing re-compilation (with OPTION(RECOMPILE)) does not have the security implications of dynamic string execution?
    Answer: Yes and no. Unfortunately, using only OPTION (RECOMPILE) as a single/uniform solution can be even more problematic. While recompilation can be helpful for some statements, it’s a waste when it’s unnecessary, it may eat up too much CPU and there are some statements that it just cannot help. In fact, if you have a system with a lot of dynamic statements and/or recompilations – you might make things worse. As a general practice I try not to use it and I tend to use it sparingly – only if I can’t come up with a better solution. For example, the optimal execution plan for some statements can vary between table scans and nonclustered index with [bookmark] lookups because of the volatility of the parameters *AND* the fact that a better index doesn’t exist. Sometimes I can create an index (usually a covering index) and make the plan more stable/consistent without requiring recompilation.
    And, there are other cases where OPTION (RECOMPILE) doesn’t help the execution plan because it’s the statement itself that is the problem. I see this often. As a generalization, I see this when the supplied parameters vary and a single procedure has been created to try and satisfy all of the possible parameter combinations (some of which might not be supplied at all). Usually the WHERE clause looks something like the following:
    WHERE (ColumnX = @variableX OR @variableX IS NULL)
    AND (ColumnY = @variableY OR @variableY IS NULL)
    AND (ColumnZ = @variableZ OR @variableZ IS NULL)

    When the procedure ends up looking like this, I call it a multi-purpose procedure. The simple fact is that when the Transact-SQL statement itself is poorly written then often even recompilation can’t help. There are some cases where building the statement dynamically yields better results - especially in cases where the number of supplied parameters (vs. those which are null) changes from execution to execution.
    It’s in these cases where I BUILD the exact statement (with only the non-null parameters) instead of one that includes numerous variables that are set to NULL. To execute the constructed statement I’ll use either: dynamic string execution or sp_executesql. Choosing which one to use correctly requires knowledge of your data, some plan analysis and thorough testing.
    As a simple rule of thumb, use sp_executesql if the plan chosen by each specific set of parameters is consistent (you’ll only know this through thorough testing). When the distribution of the data for specific parameters causes the plan to change, then use dynamic string execution (EXEC(‘string’)) rather than sp_executesql to execute the statement. And, you’ll need to protect your code from SQL Injection. To do this effectively often requires other features such as: string protection (w/REPLACE and/or QUOTENAME()), EXECUTE AS, and login-less users.
    For more information on protecting from SQL Injection, check out this post: Little Bobby Tables, SQL Injection and EXECUTE AS
    For more information on multi-purpose parameters, check out this post: Stored Procedure Parameters giving you grief in a multi-purpose procedure?
    This is definitely a complicated subject and it requires three key things:
    Knowing your data Knowing your workload Knowing how SQL Server works It’s that last one that people aren’t always looking out for. I hope this posts helps you get closer!
    Enjoy,
    kt
  19. antonch
    Νέα CUs ανακοινώθηκαν πριν 2 ημέρες από την Microsoft για τον SQL Server 2005 & 2008 R2.
    Αυτά είναι τα εξής
    KB #2489375 - SQL Server 2005 SP3 CU #14 (9.00.4317) KB #2489409 - SQL Server 2005 SP4 CU #2 (9.00.5259) KB #2489376 - SQL Server 2008 R2 CU #6 (10.50.1765) Τα περισσότερα fixes υπάρχουν σε αυτό για τον SQL Server 2008 R2.
  20. antonch
    Το πρόβλημα

    Πριν από μερικές μέρες μια συνάδελφος ήρθε με το εξής πρόβλημα, ήθελε να δείξει κάποια δεδομένα σε ένα treeview control σε ένα web page. Στην ουσία ήταν μια ιεραρχία που από την δομή του πίνακα έβγαινε αρκετά εύκολα με ένα order by clause. Όμως δεν ήταν τόσο απλά τα πράγματα, ήθελε να υπάρχει ταξινόμηση ανά επίπεδο ιεραρχίας το οποίο ορίζονταν από ένα άλλο πεδίο.

    Για να εξηγήσουμε καλύτερα την πρόκληση αυτή ας έρθουμε να δούμε το πώς ήταν τα δεδομένα της

    Ολόκληρο το άρθρο θα το βρείτε εδώ καθώς χρειάστηκε να το αναθεωρήσω
×
×
  • Create New...