Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <blockquote> <p>For example, a "Score" class has a constructor which throws a meaningful error message when construction fails (i.e. when the score is outside a valid range). First, what do you think of that approach? </p> </blockquote> <p>It worries me a bit, because calling a ctor requires memory allocation, which is relatively expensive. For each row inserted, you're calling a ctor <em>-- and only for its side-effects.</em></p> <p>Also expensive are exceptions. They're great when you need them, but this is a case where you vould use them in a ctor context, but not in a check context.</p> <p>A refactoring could reduce both costs, by having the check exist as a class static or free function, then both the check constraint and the ctor could call that:</p> <pre><code>class Score { private: int score; public: static bool valid( int score ) { return score &gt; 0 ; } Score( int s ) { if( ! valid( s ) ) { throw InvalidParameter(); } score = s; } } </code></pre> <p>Check constraint calls Score::valid(), no construction or exception needed.</p> <p>Of course, you still have the overhead, for each row, of a CLR call. Whether that's acceptable is something you'll have to decide.</p> <blockquote> <p>Is there a T-SQL statement to re-enable with check all check constraints on ALL tables, or do I have to re-enable them table by table?</p> </blockquote> <p>No, but you can do this to generate the commands:</p> <pre><code>select 'ALTER TABLE ' || name || ' WITH CHECK CHECK CONSTRAINT ALL;' from sys.tables ; </code></pre> <p>and then run the resultset against the database.</p> <p>Comments from the OP:</p> <blockquote> <p>I use base classes called ConstrainedNumber and RegexConstrainedString for all my data types. I could easily move those two classes' simple constructor code to a separate public boolean IsValueValid method as you suggested, and probably will. </p> <p>The CLR overhead (and memory allocation) would only occur for inserts and updates. Given the simplicity of the methods, and rate at which table updates will occur, I don't think the performance impact will anything to worry about for my system.</p> <p>I still really want to raise exceptions for the information they'll provide to management studio users. I like the IsValueValid method, because it gives me the 'option' of not throwing errors. Within applications using my data types, I could still get the exception by constructing an instance :)</p> </blockquote> <p>I'm not sure I agree with the exception throwing, but again, the "take-home message" is that by decomposing the problem into parts, you can select what parts you're wiling to pay for, without paying for parts you don't use. The ctor you don't use, because you were only calling it to get the side-effect. So we decomposed creation and checking. We can further decompose throwing:</p> <pre><code>class Score { private: int score; public: static bool IsValid( int score ) { return score &gt; 0 ; } static checkValid( int score ) { if( ! isValid( s ) ) { throw InvalidParameter(); } Score( int s ) { checkValid( s ) ; score = s; } } </code></pre> <p>Now a user can call the ctor, and get the check and possible exception and construction, call checkValid and get the check and exception, or isValid to just get the validity, paying the runtime cost for only what he needs.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload