Jump to content

antonch

Administrators
  • Posts

    1030
  • Joined

  • Last visited

  • Days Won

    7

Blog Entries posted by antonch

  1. antonch
    Αφού έχουμε στύψει αρκετά το μυαλό μας μέχρι τώρα και έχουμε καταφέρει να σχεδιάσουμε και να υλοποιήσουμε το DW μας και το αίσθημα της ικανοποίησης μας έχει κυριεύσει, θα πρέπει να κάνουμε το επόμενο μεγάλο βήμα πίστης που δεν είναι άλλο από το γεμίσουμε αυτό με δεδομένα.
    Είμαστε στο σημείο που πρέπει να σχεδιάσουμε και να υλοποιήσουμε μια ή περισσότερες διαδικασίες ETL (Extract-Transform-Load). Όλες αυτές οι διαδικασίες θα πρέπει να αποτελέσουν ένα Data Integration System το οποίο θα πρέπει να δίνει λύσεις σε όλα τα προβλήματα που σχετίζονται με τα δεδομένα που θα εισαχθούν στο DW. Είναι μια εργασία που θα πρέπει να λάβουμε πολλές παραμέτρους υπόψη μας. Παραμέτρους που έχουν να κάνουν αρχικά με την ποιότητα των δεδομένων και έπειτα με την αξιοπιστία, την κλιμάκωση και την διαχείριση της λύσης που θα δημιουργηθεί. Σίγουρα δεν είναι μια εύκολη δουλειά αν και αρχικά φαίνεται εύκολη καθώς έχουμε στα χέρια μας τα SQL Server Integration Services που μας βοηθάνε στο μέγιστο βαθμό, όμως ένα εργαλείο από μόνο του δεν είναι πανάκεια.
    Περισσότερα
  2. antonch
    Είναι σπάνιο το φαινόμενο σε μια λύση BI και σε ένα DW να μην ζητείται ανάλυση και reporting των δεδομένων με βάση κάποια χρονική περίοδο.
    Το σύνηθες είναι να έχω τουλάχιστον μία διάσταση χρόνου. Για το λόγο αυτό σε αυτό το post θα δούμε πως μπορούμε να σχεδιάσουμε και υλοποιήσουμε σε μια BI λύση μια τέτοια διάσταση.
    Για αρχή θα ξεκινήσουμε να δούμε την λογική με την οποία θα σχεδιάσουμε ένα time dimension.
    Περισσότερα
  3. antonch
    Είναι πρωινό της 27/10/2014. Κάνει κρύο για τα δικά μου δεδομένα και είμαι στο γραφείο στην δουλειά μου. Χτυπάει το τηλέφωνο και είναι ο Σοφοκλής.
     
    http://www.sqlschool.gr/blog/do-not-forget-to-update-index-statistics-1005.aspx
  4. antonch
    Δεν ξέρω αν σας αρέσει να ανεβαίνει η αδρεναλίνη σας ύψη αλλά προσωπικά μου αρέσει, αρκεί να είναι όπως αυτή η περίπτωση :-)
    Είμαι λοιπόν από το πρωί πάνω σε παραγωγικό server που έχει κομβικό Internet-ικο τμήμα του οργανισμού που εργάζομαι. Παλεύω να κάνω partitioning το πίνακα ημερολογίου συναλλαγών και είναι τεράστιος… Πρέπει να κάνω απλές και σίγουρες κινήσεις που δεν θα επηρεάσουν σε καμία περίπτωση την απόδοση του συστήματος.
     
    http://www.sqlschool.gr/blog/do-not-panic-when-an-error-occurred-just-learn-to-read-the-logs-1011.aspx
  5. antonch
    Οι περισσότεροι από εσάς όταν θέλετε να αλλάξετε την δομή ενός πίνακα σε μια βάση χρησιμοποιείτε το SQL Server Management Studio (SSMS) όπου με δεξί κλικ στον πίνακα κάνετε design και αφού κάνετε την αλλαγή που θέλετε πατάτε το save button από την toolbar.
     
    Είμαι σίγουρος έχετε κάνει πολλά πράγματα έτσι και έχετε μείνει απόλυτα ευχαριστημένοι. Θεωρώ επίσης βέβαιο ότι κάποια στιγμή που κάτι πάλι θέλατε να αλλάξετε αυτό δεν μπορούσε να γίνει καθώς ο SSMS σας εμφάνισε ένα παράθυρο όπως το παρακάτω.
     
    http://www.sqlschool.gr/blog/do-not-uncheck-%E2%80%9Cprevent-saving-changes-that-require-table-re-creation%E2%80%9D-option-on-ssms-1009.aspx
  6. antonch
    Πριν από ένα μήνα είχα αναρτήσει μια δημοσκόπηση στο site του SqlSchool.gr με την εξής ερώτηση:

    Έχετε ενεργοποιήσει το "Optimize for Ad Hoc Workloads" στα instances του SQL Server 2008 & R2 που έχετε;

    Η συγκεκριμένη δημοσκόπηση έγινε με αφορμή κάποιες συζητήσεις που είχα με κάποιους συναδέλφους σχετικά με θέματα performance πάνω στον SQL Server. Αν και γενικά έχουν γραφτεί στο παρελθόν αρκετά για το συγκεκριμένο θέμα πίστευα ότι το συγκεκριμένο ήταν αρκετά γνωστό. Από τις συζητήσεις όμως διαπίστωσα ότι στην χώρα μας δεν ήταν και τόσο. Θέλησα να μετρήσω περισσότερο το συγκεκριμένο έτσι και έβαλα την συγκεκριμένη δημοσκόπηση.
    Τα αποτελέσματα μετά από ένα μήνα που ήταν ενεργή η συγκεκριμένη δημοσκόπηση ήταν τα παρακάτω
    Ναί 23,08% Όχι 7,69% Εξαρτάται 0% Δεν ξέρω τι είναι αυτό 69,23% Η έκπληξη ήταν αρκετά μεγάλη βλέποντας το αποτέλεσμα και έτσι αποφάσισα να δω και τον αριθμό συμμετοχών στην δημοσκόπηση αυτή ώστε να εξασφαλίσω την εγκυρότητα του δείγματος. Ο αριθμός αυτό δεν ήταν καθόλου μικρός (173 μοναδικές συμμετοχές). Βλέποντας τον αριθμό και τα αποτελέσματα μου διαπίστωσα ότι καλά έκανα και μέτρησα το συγκεκριμένο θέμα.
    Ας πάρουμε τα πράγματα όμως με την σειρά ώστε στο τέλος να έχουμε βγάλει μια άκρη σχετικά με το τι τελικά είναι το Optimize for Ad Hoc Workloads και αν πρέπει ή όχι να το έχουμε ενεργοποιημένο .
    Τι είναι το Optimize for Ad Hoc Workloads;
    Σήμερα όλο και περισσότερες εφαρμογές χρησιμοποιούν ORMs για να διαβάσουν δεδομένα από τις databases πχ Entity Framework , Linq to SQL, NHibernate κλπ. Είναι τα αγαπημένα εργαλεία των devs που θέλουν να γράφουν σε αυτό που ξέρουν πχ C# και object oriented programming. Γενικά είναι αγαπημένα εργαλεία σε αυτούς που θέλουν να βλέπουν την βάση σαν ένα κουβά (αυτό είναι κάτι το οποίο με κάνει να εξοργίζομαι). Μέσα από τα εργαλεία αυτά ο κάθε dev χωρίς να το βασανίσει ιδιαίτερα κάνει ad hoc queries χρησιμοποιώντας τα εργαλεία αυτά. Για κάθε ένα από αυτά ο SQL Server αποθηκεύει το execution plan του στην plan cache που είναι μέρος της buffer cache που είναι και στην ουσία αυτή που καταναλώνει memory στην μηχανή που είναι εγκατεστημένος ο SQL Server. Πολλά από αυτά το πιθανότερο είναι να μην χρησιμοποιηθούνε ποτέ ξανά, αυτό σημαίνει ότι μνήμη που έχει δεσμευτεί για τα execution plans τους παραμένει κατειλημμένη. Βέβαια το ίδιο ισχύει και για εφαρμογές που δεν είναι γραμμένες χρησιμοποιώντας τα εργαλεία αυτά αλλά είναι κακογραμμένες ή ο dev δεν έχει ανακαλύψει ακόμα την χρήση των stored procedure. Σημασία όμως έχει ότι είτε έτσι είτε αλλιώς έχω αυτό που ονομάζεται plan cache bloat όπως έχει καθιερωθεί να λέγεται τα φαινόμενο αυτό στην κοινότητα των SQL Server experts.

    Plan Cache bloat means that much of your plan cache is wasted by execution plans that will never be used again.

    Το φαινόμενο αυτό μπορεί να εξαλειφθεί όταν ενεργοποιήσω το option optimize for ad hoc workloads, το οποίο by default είναι off. Με ενεργοποιημένο το option αυτό ο SQL Server αντί να αποθηκεύσει το full execution plan του ad hoc query αποθηκεύει ένα μικρό compiled plan stub όπως λέγεται κατά την πρώτη του εκτέλεση. Το full execution plan θα αποθηκευτεί όταν θα υπάρχει και επόμενη εκτέλεση του ίδιου ad hoc query.
    Πώς βρίσκω αν πρέπει να ενεργοποιήσω το Optimize for Ad Hoc Workloads;
    Για να εντοπίσω, σαν DBA, αν έχω το φαινόμενο του plan cache bloat o τρόπος είναι ένας και αυτός δεν είναι άλλος από το να χρησιμοποιήσω την DMV sys.dm_exec_cached_plans.
    Για καλύτερα όμως αποτελέσματα καλό είναι να εκτελέσετε το παρακάτω script στο οποίο γίνεται με την χρήση της sys.dm_exec_cached_plans
    declare @TotalPlanCacheSizeInMBs decimal(18,2), @TotalSingleUsedPlansInMBs decimal(18,2)
    select @TotalPlanCacheSizeInMBs = (sum(cast(size_in_bytes as decimal(18,2)))/1024)/1024
    , @TotalSingleUsedPlansInMBs = (sum(cast((case when usecounts = 1 and objtype in ('Adhoc','Prepared') then size_in_bytes else 0 end) as decimal(12,2)))/1024)/1024
    from sys.dm_exec_cached_plans
    select @TotalPlanCacheSizeInMBs AS [Total Plan Cache Size In MBs]
    , @TotalSingleUsedPlansInMBs AS [Total Single Used Plans In MBs]
    , cast((@TotalSingleUsedPlansInMBs * 100 ) / @TotalPlanCacheSizeInMBs as decimal(18,2)) AS [% of Wasted space from single used plans]
    go



    Αν το % of Wasted space from single used plans είναι πάνω από το 20% (αν και το ποσοστό αυτό μπορεί να αλλάξει ανάλογα με το περιβάλλον) τότε καλό είναι να ενεργοποιηθεί το option αν και βέβαια αυτή είναι μια εκτίμηση γίνεται σε βάση την σχέση του χαμένου χώρου και του συνολικό μέγεθος της plan cache.


    Αν θέλουμε μπορούμε να δούμε πόσο χώρο χάνουμε σε σχέση με την γενικότερη μνήμη που ο SQL Server καταναλώνει με το παρακάτω script


    declare @SQLConfiguration table
    ( [name] nvarchar(35)
    , [minimum] int
    , [maximum] int
    , [config_value] int
    , [run_value] int
    );

    insert @SQLConfiguration
    exec ('sp_configure ''max server memory''');

    DECLARE @ConfiguredMemory decimal(19,3)
    , @PhysicalMemory decimal(19,3)
    , @InUseMemory decimal(19,3)


    SELECT @ConfiguredMemory = (run_value/1024)/1024
    FROM @SQLConfiguration
    WHERE name = 'max server memory (MB)'

    SELECT @PhysicalMemory = total_physical_memory_kb/1024
    FROM sys.dm_os_sys_memory

    SELECT @InUseMemory = physical_memory_in_use_kb/1024
    FROM sys.dm_os_process_memory

    declare @TotalSingleUsedPlansInMBs decimal(18,2)
    select @TotalSingleUsedPlansInMBs = (sum(cast((case when usecounts = 1 and objtype in ('Adhoc','Prepared') then size_in_bytes else 0 end) as decimal(12,2)))/1024)/1024
    from sys.dm_exec_cached_plans
    select @ConfiguredMemory AS [sql Configured Memory]
    , @PhysicalMemory AS [Physical Memory]
    , @InUseMemory AS [used Memory by SQL Server]
    , cast((@InUseMemory * 100 ) / @ConfiguredMemory as decimal(18,2)) AS [% of SQL Server used memory on Configured Memory]
    , @TotalSingleUsedPlansInMBs AS [Total Single Used Plans In MBs]
    , cast((@TotalSingleUsedPlansInMBs * 100 ) / @ConfiguredMemory as decimal(18,2)) AS [% of Wasted space from single used plans on Configured Memory]
    , cast((@TotalSingleUsedPlansInMBs * 100 ) / @InUseMemory as decimal(18,2)) AS [% of Wasted space from single used plans on Used Memory]
    go


    Εάν έχουμε [% of SQL Server used memory on Configured Memory] πάνω από το 50% και δούμε το [% of Wasted space from single used plans on Used Memory] να είναι πάνω από το 10-15% τότε είναι ένα καλό σημάδι να ενεργοποιήσουμε option.


    Τέλος υπάρχει ακόμα και περίπτωση που αν θέλουμε μπορούμε να κοιτάξουμε σε σχέση όμως αυτή την φορά με την Plan Cache Pressure Limit . Για να το γίνει αυτό θα πρέπει να γνωρίζουμε πως δουλεύει το plan caching στον SQL Server. Για αυτό υπάρχει ένα εξαιρετικό white paper από τον Greg Low με τίτλο Plan Caching in SQL Server 2008 από το οποίο ιδιαίτερη μνεία θα πρέπει να δοθεί στην παράγραφο με τίτλο Memory Allocated To Plan Caching την οποία και μεταφέρω αυτούσια για την ευκολία στο διάβασμα του post.




    Most memory used by SQL Server is allocated to the Buffer Pool, which is used to store data pages. SQL Server steals a proportion of this memory for use in caching query plans. The overall amount of memory available to SQL Server depends upon the amount of memory installed on the server, the architecture of the server, the version and edition of SQL Server and the amount of memory pressure being experienced by SQL Server. This pressure can be internal (SQL Server resources need memory) or external (operating system needs memory). SQL Server is designed to respond to memory pressure when necessary.


    Four types of object are stored in the Plan Cache: Object Plans, SQL Plans, Bound Trees and Extended Stored Procedures. SQL Server decides the appropriate allocation of memory to the Plan Cache from the Buffer Pool. The algorithm used for this has been improved in successive service packs since SQL Server 2005 was introduced.





    SQL Server Version




    Cache Pressure Limit






    SQL Server 2008 and SQL Server 2005 SP2




    75% of visible target memory from 0-4GB + 10% of visible target memory from 4Gb-64GB + 5% of visible target memory > 64GB






    SQL Server 2005 RTM and SQL Server 2005 SP1




    75% of visible target memory from 0-8GB + 50% of visible target memory from 8Gb-64GB + 25% of visible target memory > 64GB






    SQL Server 2000




    SQL Server 2000 4GB upper cap on the plan cache






    Table 1: Plan cache memory allocation by SQL Server version


    While 32-bit systems may use AWE (Address Window Extensions) memory to extend the available memory beyond the 4G virtual address space limit of the 32-bit architecture, this additional memory can only be used for data pages in the Buffer Pool, not by pages in the Plan Cache. It is not considered visible memory. No such limitation applies to 64-bit systems.




    Για την ευκολία σας θα αναφέρω το παρακάτω από το βιβλίο της Kalen Delaney SQL Server Internals όπου ορίζονται με εξαιρετικό τρόπο τα παρακάτω:




    When discussing memory pressure, we refer to the term visible memory—that is, the directly addressable physical memory available to the SQL Server buffer pool. On a 32-bit SQL Server instance, the maximum value for visible memory is either 2GB or 3GB, depending on whether you have the /3GB flag set in your boot.ini file. Memory with addresses greater than 2GB or 3GB is available only indirectly, through AWE-mapped memory. On a 64-bit SQL Server instance, “visible” memory has no special meaning, as all the memory is directly addressable. If I refer to visible memory greater than 3GB, keep in mind that this is possible only on a 64-bit SQL Server system. The term target memory means the maximum amount of memory that can be committed to the SQL Server process. Target memory refers to the physical memory committed to the buffer pool and is the lesser of the values you’ve configured for “max server memory” and the total amount of physical memory available to the OS. Thus, visible target memory is the visible portion of the target memory. Query plans can be stored only in the non–AWE-mapped memory, which is why the concept of visible memory is important.




    Από το ίδιο βιβλίο θα πάρω και ένα παράδειγμα




    Assume you’re on SQL Server 2008 on a 64-bit SQL Server instance with 28GB of target memory. Per the formula in Table 1, the plan-cache pressure limit would be 75 percent of 4GB plus 10 percent of the target memory over 4GB (or 10 percent of 24GB)—that is, (.75 × 4GB) + (.10 × 24GB) = 3GB + 2.4GB = 5.4GB.




    Αφού εφαρμόσουμε τον παραπάνω αλγόριθμο βρίσκουμε το plan cache pressure limit και το συσχετίζουμε με τον αποτελέσματα από τον πρώτο τρόπο. Αν το ποσοστό που θα βρούμε είναι μεγάλο τότε όχι μόνο θα πρέπει να ενεργοποιήσουμε το option αλλά να κάνουμε καθαρισμό της plan cache. Βέβαια αυτό θα πρέπει να γίνει και για τι άλλες περιπτώσεις που έχω αναφέρει παραπάνω.


    Πώς καθαρίζω την Plan Cache


    Ο εύκολος τρόπος για να γίνει αυτό είναι να χρησιμοποιήσω την


    DBCC FREESYSTEMCACHE('SQL Plans')

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


    select plan_handle from sys.dm_exec_cached_plans
    where usecounts=1
    go

    DECLARE clearplancache CURSOR
    READ_ONLY
    FOR select plan_handle from sys.dm_exec_cached_plans

    DECLARE @plan_handle varbinary(8000)
    OPEN clearplancache

    FETCH NEXT FROM clearplancache INTO @plan_handle
    WHILE (@@fetch_status -1)
    BEGIN
    IF (@@fetch_status -2)
    BEGIN
    DBCC FREEPROCCACHE (@plan_handle)
    END
    FETCH NEXT FROM clearplancache INTO @plan_handle
    END

    CLOSE clearplancache
    DEALLOCATE clearplancache
    GO
    select plan_handle from sys.dm_exec_cached_plans
    where usecounts=1
    go



    Πώς ενεργοποιώ το Optimize for Ad Hoc Workloads;


    Για να ενεργοποιήσω το συγκεκριμένο option μπορώ να το κάνω με το εξής script


    sp_configure 'show advanced options',1
    go

    reconfigure
    go

    sp_configure 'optimize for ad hoc workloads',1
    go

    reconfigure
    go
  7. 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%
  8. antonch
    Εισαγωγή
    Το τελευταίο διάστημα στα μαθήματα και τις παρουσιάσεις που έχω κάνει όλο και περισσότεροι έρχονται και με ρωτούν τι πρέπει να κάνουν για το deadlock καθώς όπως μου λένε έχουν όλο και περισσότερες εμφανίσεις του φαινομένου αυτού.
    Πάντα απαντώ σε όλους αυτά που θα ακολουθήσουν σε αυτό το post αλλά μέχρι τώρα δεν τα είχα γράψει και νομίζω ότι πλέον είναι καιρός να γίνει αυτό.
    περισσότερα
  9. antonch
    Τις τελευταίες ημέρες για ένα περίεργο λόγο συνάντησα αρκετές φορές την ανάγκη να πρέπει να εκτιμηθεί η δυνατότητα να γίνει compress μια database. Για το λόγο αυτό αποφάσισα να φτιάξω μια stored procedure που να κάνει όλα όσα ήθελα να γίνονται με την εκτέλεση της. Μετά από μερικές μέρες δουλειάς και αρκετές αλλαγές πάνω σε αυτή το τελικό αποτέλεσμα μπορείτε να το βρείτε εδώ.
    Όμως πριν αρχίσετε να την χρησιμοποιείται νομίζω ότι είναι σκόπιμο να διαβάσετε το documentation αυτής και τις δυνατότητες που παρέχει.
    Πριν όμως το κάνω αυτό θα πρέπει να επισημάνω ότι το database compression είναι ένα feature το οποίο εμφανίστηκε στον SQL Server 2008 Enterprise Edition άρα η stored procedure αυτή μπορεί να δουλέψει από αυτή την έκδοση και πάνω, δηλαδή 2008, 2008R2 και 2012.
    Επίσης ο χρήστης που θα την εκτελέσει θα πρέπει να έχει δικαιώματα sysadmin.
    περισσότερα
  10. antonch
    Άλλοι περισσότερο άλλοι λιγότερο χρησιμοποιούμε το SQL Server Management Studio στην καθημερινότητα μας.
    Μέσα σε αυτή εκτελούμε και αρκετά queries είτε σε πίνακες της βάσης μας είτε σε metadata tables. Το κάνουμε σχεδόν μηχανικά καθημερινά έτσι δεν είναι;

    Όπως επίσης είναι γνωστό ότι μπορούμε να δούμε τα αποτελέσματα αυτών σε διαφορετικές μορφές όπως grid, text, file.
    περισσότερα
  11. antonch
    O SQL Server έχει αρκετά εργαλεία για να κάνεις export & import data. Από τα απλά T-SQL BULK INSET ή το κλασσικό BCP μέχρι τα DTS (Data Transformation Services)  και σήμερα τα SSIS ( SQL Server Integration Services).

    Όμως υπάρχουν αρκετές περιπτώσεις που δεν θα ήθελες να εμπλακείς με αυτά.

    Ένα σενάριο το οποίο κάποια στιγμή σε ένα project μου έτυχε ήταν η απαίτηση να πατάει ο χρήστης ένα κουμπί και να γίνονται τα δεδομένα export σε Excel αρχείο.

    Για να δούμε λοιπόν την υλοποίηση του χωρίς να χρησιμοποιήσω κάτι από τα παραπάνω αλλά κάνοντας χρήση αγνού T-SQL και της δυνατότητας που έχει ο SQL Server με τους Linked Servers.

    Βασική προϋπόθεση για να μπορέσει η λύση να δουλέψει είναι να δημιουργήσεις ένα άδειο αρχείο excel στο server με συγκεκριμένο όνομα και σε συγκεκριμένο directory. Ας το πούμε empty.xls και ας το βάλουμε στο c:\temp. Αυτό θα λειτουργεί σαν template για τα αρχεία που δα δημιουργήσουμε παρακάτω.

    Όμως δεν φτάνει μόνο αυτό.

    Θα πρέπει να ανοίξω το excel αρχείο και να δώσω ένα όνομα στο φύλλο (πχ MyData).

    Ακόμα θα πρέπει να γνωρίζω πόσα πεδία θα βάλω στο excel φύλλο πχ αν ξέρω ότι θα βάλω 2 πεδία θα πρέπει στα πρώτα 2 κελιά της πρώτης γραμμής να δώσω κάποιο όνομα πχ A,B.

    Φτιάχνω την stored procedure που θα κάνει όλη την δουλειά


    create proc usp_write2Excel (@fileName varchar(100),@NumOfColumns tinyint,@query varchar(200))

    as

    begin

    declare @dosStmt varchar(200)

    declare @tsqlStmt varchar(500)

    declare @colList varchar(200)

    declare @charInd tinyint

    set nocount on

    --
    -- COLUMNS LIST CREATION

    --
    set @charInd=0

    set @colList = 'A'

    while @charInd
    begin

    set @charInd = @charInd + 1

    set @colList = @colList + ',' + char(65+ @charInd)

    end

    -- CREATE MY EXCEL FILE BY COPING EXCEL TEMPLATE

    set @dosStmt = ' copy c:\temp\empty.xls ' + @fileName

    exec master..xp_cmdshell @dosStmt

    -- Create a "temporary" linked server to that file in order to "Export" Data

    EXEC sp_addlinkedserver 'ExcelSource','Jet 4.0','Microsoft.Jet.OLEDB.4.0',@fileName,NULL,'Excel 5.0'

    -- construct a T-SQL statement that will actually export the query results-- to the Table in the target linked server

    set @tsqlStmt = 'Insert ExcelSource...[MyData$] ' + ' ( ' + @colList + ' ) '+ @query

    -- execute dynamically the TSQL statement

    exec (@tsqlStmt)

    -- drop the linked server

    EXEC sp_dropserver 'ExcelSource'

    set nocount off

    end

    GO

    Execute sp

    exec usp_write2Excel 'c:\temp\Customers.xls',2,'select customerid,companyname from northwind.dbo.customers'




    Αυτό ήταν έχεις τα δεδομένα σου σε Excel!!!  
  12. antonch
    Πριν από τρία χρόνια είχα γράψει ένα post με αυτό το θέμα. Το συγκεκριμένο post είναι από τα δημοφιλή θα έλεγα και έχει αρκετούς, από όσο γνωρίζω που έχουν χρησιμοποιήσει την συγκεκριμένη πρόταση.Παρόλα αυτά όμως το παλαιό post χρειάζεται ένα refactoring καθώς από τότε που γράφτηκε μέχρι σήμερα έχουν μεσολαβήσει αρκετές αλλαγές που σε αρκετές περιπτώσεις δεν θα δουλέψει. Για αυτό σε αυτό δίνω μια νέα βελτιωμένη εκδοχή.
    more
  13. antonch
    Σήμερα ένας αγαπητός φίλος και συνάδελφος μου έστειλε mail και με ρωτούσε

    Αντώνη καλησπέρα,
    Πως μπορώ να κάνω convert απο nvarchar se iso-8859-7 μέσω SSIS για να το κάνω export σε Flatfile?

    Η απάντηση είναι η εξής
    Tην στιγμή που ορίζω τον connection manager στο παραγόμενο flat file όριζω στο Code Page του αρχείου την τιμή 28597 (ISO 8859-7 Greek)

    Υπάρχει βέβαια η περίπτωση σε πεδία τα οποία είναι ntext ή nvarchar(max) να μου γκρινίαζει και να μου λέει ότι δεν μπορεί να τα μετατρέψει αλλά και πάλι υπάρχει λύση, βάζω ένα Data Conversion Task

    στο οποίο ορίζω τα παρακάτω

    και το αρχείο μου παράγεται όπως το θέλω αφού βέβαια στα mappings βάλω την νέα κολώνα

    @antonch
  14. antonch
    Σήμερα είχα μια ωραία ερώτηση από μια αγαπητή συνάδελφο σχετικά με τον τελεστή LIKE. Η ερώτηση της ήταν:

    «Πως μπορώ να έχω την δυνατότητα με τον τελεστή LIKE να έχω όλα τα records που είναι περασμένα μέσα στην βάση μου σε ένα πίνακα ακόμα και στην περίπτωση που έχουν περαστεί κάποιοι χαρακτήρες με ελληνικά και κάποιοι με αγγλικά;»

    Στην ουσία αυτό που ήθελε ήταν αν έχω ένα πεδίο σε ένα πίνακα μου και έχω περάσει κάποια records που σε αυτό να έχω τις τιμές Antonis, Αντonis, Αntώνης εάν δώσω Antonis ή Αντώνης να μου τα φέρνει όλα.

    Αυτό γίνεται εύκολα αρκεί να χρησιμοποιήσεις για κάθε χαρακτήρα της λέξης που βάζει στο Like το pattern με τις αγκύλες στο οποίο ορίζεις τους χαρακτήρες που θα ψάξεις

    Πχ

    Έστω ότι έχω τον παρακάτω πίνακα
    create table tbLike
    ( id int identity(1,1) primary key,
    memo nvarchar(100))
    Στον οποίο περνάω 2 records
    insert into tbLike values ('λαλα'),('λaλa')
    και θέλω να μου φέρει και τα δύο records to query μου θα πρέπει να είναι το παρακάτω
    select * from tbLike where memo like 'λ[aα]λ[aα]'
    Επειδή αυτό θέλω να κατασκευάζεται αυτόματα τις έφτιαξα μια user define function η οποία παίρνει σαν παράμετρο το input του χρήστη και φτιάχνει το pattern me κάποιες παραδοχές όσον αφορά την αντιστοιχία των ελληνικών και αγγλικών γραμμάτων.

    Αυτή είναι η παρακάτω

    (σημείωση: Έχω προτιμήσει να την γράψω με τον απλούστερο τρόπο ώστε να είναι εύκολα μετατρέψιμη ακόμα και από κάποιον που ξέρει τα βασικά σε Τ-SQL)
    1: create function fnGreekEnglishLikeString(@instring nvarchar(100)) returns nvarchar(100)
    2: as
    3: begin
    4: --abcdefghijklmnopqrstuvwxyz
    5: --αβγδεζηθικλμνξοπρστυφχψω
    6:
    7: declare @rv nvarchar(100)
    8: declare @i int = 1
    9: declare @length int
    10: select @length = len(@instring)
    11: declare @s nvarchar(10)
    12: set @rv=''
    13: while @i
    14: begin
    15: set @s=''
    16: select @s=case
    17: when substring(@instring,@i,1) = 'a' or substring(@instring,@i,1) = 'α' then '[aα]'
    18: when substring(@instring,@i,1) = 'b' or substring(@instring,@i,1) = 'β' then '[bβv]'
    19: --when substring(@instring,@i,1) = 'c' or substring(@instring,@i,1) = '.' then '[bβ]'
    20: when substring(@instring,@i,1) = 'd' or substring(@instring,@i,1) = 'δ' then '[dδ]'
    21: when substring(@instring,@i,1) = 'e' or substring(@instring,@i,1) = 'ε' then '[eε]'
    22: when substring(@instring,@i,1) = 'f' or substring(@instring,@i,1) = 'φ' then '[fφ]'
    23: when substring(@instring,@i,1) = 'g' or substring(@instring,@i,1) = 'γ' then '[gγ]'
    24: when substring(@instring,@i,1) = 'h' or substring(@instring,@i,1) = 'β' then '[hηiι]'
    25: when substring(@instring,@i,1) = 'i' or substring(@instring,@i,1) = 'ι' then '[iιhη]'
    26: --when substring(@instring,@i,1) = 'j' or substring(@instring,@i,1) = 'β' then '[bβ]'
    27: when substring(@instring,@i,1) = 'k' or substring(@instring,@i,1) = 'κ' then '[kκ]'
    28: when substring(@instring,@i,1) = 'l' or substring(@instring,@i,1) = 'λ' then '[lλ]'
    29: when substring(@instring,@i,1) = 'm' or substring(@instring,@i,1) = 'μ' then '[mμ]'
    30: when substring(@instring,@i,1) = 'n' or substring(@instring,@i,1) = 'ν' then '[nν]'
    31: when substring(@instring,@i,1) = 'o' or substring(@instring,@i,1) = 'ο' then '[oοω]'
    32: when substring(@instring,@i,1) = 'p' or substring(@instring,@i,1) = 'π' then '[pπ]'
    33: --when substring(@instring,@i,1) = 'q' or substring(@instring,@i,1) = 'β' then '[bβ]'
    34: when substring(@instring,@i,1) = 'r' or substring(@instring,@i,1) = 'ρ' then '[rρ]'
    35: when substring(@instring,@i,1) = 's' or substring(@instring,@i,1) = 'σ' or substring(@instring,@i,1) = 'ς' then '[sσς]'
    36: when substring(@instring,@i,1) = 't' or substring(@instring,@i,1) = 'τ' then '[tτ]'
    37: when substring(@instring,@i,1) = 'u' or substring(@instring,@i,1) = 'υ' then '[uυy]'
    38: when substring(@instring,@i,1) = 'v' or substring(@instring,@i,1) = 'β' then '[vβb]'
    39: --when substring(@instring,@i,1) = 'w' or substring(@instring,@i,1) = 'β' then '[bβ]'
    40: when substring(@instring,@i,1) = 'x' or substring(@instring,@i,1) = 'χ' then '[xχ]'
    41: when substring(@instring,@i,1) = 'y' or substring(@instring,@i,1) = 'υ' then '[uυy]'
    42: when substring(@instring,@i,1) = 'z' or substring(@instring,@i,1) = 'ζ' then '[zζ]'
    43: else '['+substring(@instring,@i,1)+']'
    44: end
    45: set @rv=@rv+@s
    46: set @i+=1
    47: end
    48: return @rv
    49: end
    50: go
    Εάν κάποιος θέλει να δει το αποτέλεσμα που επιστρέφει η συγκεκριμένη function αρκεί να εκτελέσει το παρακάτω query
    select dbo.fnGreekEnglishLikeString('antonis')
    go
    Εάν τώρα θέλει να το ενσωματώσει στο query του
    select * from tbLike
    where memo like dbo.fnGreekEnglishLikeString('antonis')
    go
    Happy T-SQL Programming
  15. antonch
    This is copy-paste from the original article
    We’re thrilled to offer another free ebook: Own Your Future: Update Your Skills with Resources and Career Ideas from Microsoft, by Katherine Murray. The ebook contains eight chapters and an appendix describing how you can assess and build your technology-based job skills.
    To give you a sense of the ebook’s content, here is its Foreword, by Microsoft Learning’s Lutz Ziob:

    Foreword

    In the midst of a struggling economy, our fast-changing, knowledge-based economy has created unprecedented challenges for employers and workers alike. Employers increasingly need workers with a broad range of information technology (IT) skills. These skills will become even more important as we continue to retool major sectors of our economy, such as healthcare, transportation and energy. By 2014, more than three-quarters of all jobs in the United States will require some level of computing or technology skills, and the vast majority of newly created jobs will require post-secondary education or training. To meet this demand, students need a solid foundation in science, technology, engineering, math, and design, as well as in related disciplines such as computer science. And this means that workforce training systems need to be improved and expanded to meet the needs of all workers—the underemployed, the unemployed, and students who need better access to the requisite skills. Everyone entering or already in the workforce should have access to the resources they need to become lifelong learners who can adapt to an ever-changing workplace.
    Technology is only one piece of the puzzle, but it has a pivotal role to play in these efforts. It can offer students, workers, and employers the training tools they need, and it can help to quickly and efficiently expand access to educational resources. IT also helps people develop other essential 21st-century skills such as collaboration and teamwork, finding and interpreting information, and using data to aid in decision making.
    In this book, students will find a wealth of Microsoft resources they can
    use to identify the technology skills they need, and gather knowledge and experience to help them take charge of their careers. Here at Microsoft, we care about students’ career success and hope these resources will open doors to learning that will lead them to better opportunities and a deeper understanding of the way technology continues to change and improve the ways people work—both here in the U.S. and around the world.
    Lutz Ziob
    Microsoft Learning General Manager
    You can download the ebook in XPS format here and in PDF format here.
    We hope that you find this material useful. Please leave us a comment and let us know!
  16. 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.
     
    Καλή Χρονιά σε όλες και όλους
     

     
  17. antonch
    Στο SQL Saturday Night αυτό, θα δούμε τις δυνατότητες που μας έχουν έρθει για το Full Text Search στον SQL Server 2012, αλλά και όσα πρέπει να γνωρίζουμε για αυτούς είτε είμαστε DBA είτε DB Developers.
    Εγγραφή (είναι δωρεάν)
  18. antonch
    Ένα νέο γκάλοπ έχει αναρτηθεί στον www.sqlschool.gr με την παρακάτω ερώτηση


    Εάν είστε αυτός που πρέπει να επιλέξει ένα νέο server για τον βασικό database server στην εταιρία σας, αλλά έχετε περιορισμένο budget, σε τι από τα παρακάτω δεν θα κάνετε «εκπτώσεις» στα χαρακτηριστικά του και στις δυνατότητες του;


    Παρακαλώ θερμά για την συμμετοχή σας.

    /*antonch*/
  19. antonch
    Σκεφτόμαστε να αλλάξουμε την ημέρα διεξαγωγής των SQL Saturday Nights. Ποιά ημέρα θα προτιμούσατε να γίνονται;

    Επειδή η γνώμη σας μετράει θα θέλαμε να απαντήσετε στην δημοσκόπηση που κάνουμε και την οποία θα βρείτε στο www.sqlschool.gr.

    Αν έχετε κάποια διαφορετική πρόταση από αυτές που η ψηφοφορία έχει θα θέλαμε να την ξέρουμε και αυτό μπορείτε να το κάνετε αφήνοντας το σχόλιο σας σε αυτό το post

    Σας ευχαριστούμε για την συνεργασία και το χρόνο σας.
  20. antonch
    Η δύναμη της συνήθειας είναι το μεγαλύτερο ναρκωτικό του μυαλού και δεν το αφήνει να σκεφτεί αποδοτικά. Αλήθεια πόσες φορές κάνουμε μηχανικά κάποια πράγματα επειδή τα έχουμε συνηθίσει στα τόσα χρόνια που κάνουμε αυτή την δουλειά ;
     
    http://www.sqlschool.gr/blog/get-all-tables-row-count-without-using-count-function-1058.aspx
  21. antonch
    Ένα ερώτημα που με ρωτάνε συνέχεια όλοι. Μάλιστα στο πρώτο SQL Saturday που έγινε στην Ελλάδα το Σάββατο 4/10/2014 η συγκεκριμένη ερώτηση είχε μεγάλο σουξέ.
    Για αυτό λοιπόν θα την απαντήσω και γραπτώς ώστε να είναι εύκολα αναγνώσιμη από όλους σας.
    http://www.sqlschool.gr/blog/how-often-i-have-to-do-rebuild-or-reorganize-indexes-in-my-database-1003.aspx
  22. antonch
    Φαντάζομαι ότι σε όλους είναι γνωστό ότι για να εκτελεστεί ένα query στον SQL Server περνάει από τον Query Optimizer. Αυτός για να παράξει το execution plan βλέπει τα index statistics. Αυτό σημαίνει ότι όσο καλύτερα ενημερωμένα είναι αυτά τόσο καλύτερα αποτελέσματα θα δώσει ο Query Optimizer.


    Πότε όμως αυτά έχουν ενημερωθεί τελευταία φορά;

    Αν κάποιος θέλει να δώσει απάντηση στο ερώτημα του αυτό δεν έχει παρά να εκτελέσει το παρακάτω query στην βάση του.
    περισσότερα
×
×
  • Create New...