﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-kooyee ‘s blog-随笔分类-Database数据库技术</title><link>http://www.blogjava.net/Javawind/category/24926.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 28 May 2008 19:32:44 GMT</lastBuildDate><pubDate>Wed, 28 May 2008 19:32:44 GMT</pubDate><ttl>60</ttl><item><title>【PL/SQL】 Comment</title><link>http://www.blogjava.net/Javawind/archive/2008/05/27/203343.html</link><dc:creator>kooyee</dc:creator><author>kooyee</author><pubDate>Tue, 27 May 2008 14:28:00 GMT</pubDate><guid>http://www.blogjava.net/Javawind/archive/2008/05/27/203343.html</guid><wfw:comment>http://www.blogjava.net/Javawind/comments/203343.html</wfw:comment><comments>http://www.blogjava.net/Javawind/archive/2008/05/27/203343.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/Javawind/comments/commentRss/203343.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Javawind/services/trackbacks/203343.html</trackback:ping><description><![CDATA[<h2 class="HeadA"><a name="94685"></a>Using Comments Effectively</h2>
<p class="Body">The object of an effective coding style is to make the program more understandable and maintainable. Most programs will benefit from documentation which explains what is going on inside those programs. There are two forms of code documentation: external and internal. External documentation is descriptive information about a program which is written and stored separately from the program itself. Internal documentation, also known as inline documentation or comments, is placed within the program itself, either at the program level or the statement level. (For an introduction to inline documentation and the types of PL/SQL comments, see the section called "Comments" in Chapter 2.)
<p class="Body">The best kind of internal documentation derives from your programming style. If you apply many of the guidelines in this chapter and throughout this book, you will be able to write code which is, to a great extent, self-documenting. Here are some general tips:
<ul>
    <li class="ListBullet">Write straightforward code that avoids clever tricks.
    <p>&nbsp;</p>
    <li class="ListBullet">Think of names for variables and modules that accurately describe their purpose.
    <p>&nbsp;</p>
    <li class="ListBullet">Use named constants instead of literal values.
    <p>&nbsp;</p>
    <li class="ListBullet">Employ a clean, consistent layout.
    <p>&nbsp;</p>
    </li>
</ul>
<p class="Body">Do all these things and more, and you will find that you need to write fewer comments to explain your code.
<p class="Body">Reducing the need for comments is important. Few developers make or have the time for extensive documentation in addition to their development efforts, and, more importantly, many comments tend to duplicate the code. This raises a maintenance issue because those comments will have to be changed when the code is changed.
<p class="Body">While it is my hope that after reading this book you will write more self-documenting code, there is little doubt that you will still need to comment your code. The following example shows the use of single- and multiline comments in PL/SQL:
<pre><code class="CodeIndent">PROCEDURE calc_totals (company_id IN NUMBER,--The company key</code>
<code class="CodeIndent">                       total_type IN VARCHAR2--ALL or NET</code>
<code class="CodeIndent">                      );</code>
<code class="CodeIndent">&nbsp;</code>
<code class="CodeIndent">/*</code>
<code class="CodeIndent">|| For every employee hired more than five years ago,</code>
<code class="CodeIndent">|| give them a bonus and send them an e-mail notification.</code>
<code class="CodeIndent">*/</code>
<code class="CodeIndent">FOR emp_rec IN emp_cur (ADD_MONTHS (SYSDATE, -60))</code>
<code class="CodeIndent">LOOP</code>
<code class="CodeIndent">   apply_bonus (emp_rec.employee_id);</code>
<code class="CodeIndent">   send_notification (emp_rec.employee_id);</code>
<code class="CodeIndent">END LOOP;</code>
<code class="CodeIndent">&nbsp;</code>
<code class="CodeIndent">-- IF :SYSTEM.FORM_STATUS = 'CHANGED' THEN COMMIT; END IF;</code>
<code class="CodeIndent">&nbsp;</code>
<code class="CodeIndent">FUNCTION display_user </code>
<code class="CodeIndent">   (user_id IN NUMBER /* Must be valid ID */, user_type IN VARCHAR2)</code>
</pre>
<p class="Body">The first example uses the single-line comment syntax to include endline descriptions for each parameter in the procedure specification. The second example uses a multiline comment to explain the purpose of the FOR loop. The third example uses the double-hyphen to comment out a whole line of code. The last example embeds a comment in the middle of a line of code using the block comment syntax.
<p class="Body">These two types of comments offer the developer flexibility in how to provide inline documentation. The rest of this section offers guidelines for writing effective comments in your PL/SQL programs.
<h3 class="HeadB">Comment As You Code</h3>
<p class="Body">It is very difficult to make time to document your code after you have finished writing your program. Psychologically, you want to (and often need to) move on to the next programming challenge after you get a program working.
<p class="Body">You may also have a harder time writing your comments once you have put some distance between your brain cells and those lines of code. Why exactly did you write the loop that way? Where precisely is the value of that global variable set? Unless you have total recall, post-development documentation can be a real challenge.
<p class="Body">The last and perhaps most important reason to write your comments as you write your code is that the resulting code will have fewer bugs and (independent of the comments themselves) be easier to understand.
<p class="Body">When you write a comment you (theoretically) explain what your code is meant to accomplish. If you find it difficult to come up with that explanation, there is a good chance that you lack a full understanding of what the program does or should do.
<p class="Body">The effort that you make to come up with the right comment will certainly improve your comprehension, and may also result in code correction. In this sense, good inline documentation can be as beneficial as a review of your code by a peer. In both cases, the explanation will reveal important information about your program.
<h3 class="HeadB">Explain the Why--Not the How--of Your Program</h3>
<p class="Body">What do you think of the comments in the following Oracle Forms trigger code?
<pre><code class="CodeIndent">-- If the total compensation is more than the maximum...</code>
<code class="CodeIndent">IF :employee.total_comp &gt; maximum_salary</code>
<code class="CodeIndent">THEN</code>
<code class="CodeIndent">   -- Inform the user of the problem.</code>
<code class="CodeIndent">   MESSAGE ('Total compensation exceeds maximum. Please re-enter!');</code>
<code class="CodeIndent">&nbsp;</code>
<code class="CodeIndent">   -- Reset the counter to zero.</code>
<code class="CodeIndent">   :employee.comp_counter := 0;</code>
<code class="CodeIndent">&nbsp;</code>
<code class="CodeIndent">   -- Raise the exception to stop trigger processing.</code>
<code class="CodeIndent">   RAISE FORM_TRIGGER_FAILURE;</code>
<code class="CodeIndent">END IF;</code>
</pre>
<p class="Body">None of these comments add anything to the comprehension of the code. Each comment simply restates the line of code, which in most cases is self-explanatory.
<p class="Body">Avoid adding comments simply so that you can say, "Yes, I documented my code!" Rely as much as possible on the structure and layout of the code itself to express the meaning of the program. Reserve your comments to explain the Why of your code: What business rule is it meant to implement? Why did you need to implement a certain requirement in a certain way?
<p class="Body">In addition, use comments to translate internal, computer-language terminology into something meaningful for the application. Suppose you are using Oracle Forms GLOBAL variables to keep track of a list of names entered. Does the following comment explain the purpose of the code or simply restate what the code is doing?
<pre><code class="CodeIndent">/* Set the number of elements to zero. */</code>
<code class="CodeIndent">:GLOBAL.num_elements := 0;</code>
</pre>
<p class="Body">Once again, the comment adds no value. Does the next comment offer additional information?
<pre><code class="CodeIndent">/* Empty the list of names. */</code>
<code class="CodeIndent">:GLOBAL.num_elements := 0;</code>
</pre>
<p class="Body">This comment actually explains the purpose of the assignment of the global to zero. By setting the number of elements to zero, I will have effectively emptied the list. This comment has translated the "computer lingo" into a description of the effect of the statement. Of course, you would be even better off hiding the fact that you use this particular global variable to empty a list and instead build a procedure as follows:
<p class="CodeIndentKeep">PROCEDURE empty_list IS
<p class="CodeIndentKeep">BEGIN
<p class="CodeIndentKeep">:GLOBAL.num_elements := 0;
<pre><code class="CodeIndent">END;</code>
</pre>
<p class="Body">Then to empty a list you would not need any comment at all. You could simply include the statement:
<pre><code class="CodeIndent">empty_list;</code>
</pre>
<p class="Body">and the meaning would be perfectly clear.
<h3 class="HeadB">Make Comments Easy to Enter and Maintain</h3>
<p class="Body">You shouldn't spend a lot of time formatting your comments. You need to develop a style that is clean and easy to read, but also easy to maintain. When you have to change a comment, you shouldn't have to reformat every line in the comment. Lots of fancy formatting is a good indication that you have a high-maintenance documentation style. The following block comment is a maintenance nightmare:
<pre><code class="CodeIndent">/*</code>
<code class="CodeIndent">===========================================================</code>
<code class="CodeIndent">| Parameter          Description                          |</code>
<code class="CodeIndent">|                                                         |</code>
<code class="CodeIndent">| company_id         The primary key to company           |</code>
<code class="CodeIndent">| start_date         Start date used for date range       |</code>
<code class="CodeIndent">| end_date           End date for date range              |</code>
<code class="CodeIndent">===========================================================</code>
<code class="CodeIndent">*/</code>
</pre>
<p class="Body">The right-justified vertical lines and column formatting for the parameters require way too much effort to enter and maintain. What happens if you add a parameter with a very long name? What if you need to write a longer description? A simpler and more maintainable version of this comment might be:
<pre><code class="CodeIndent">/*</code>
<code class="CodeIndent">===========================================================</code>
<code class="CodeIndent">| Parameter - Description               </code>
<code class="CodeIndent">|                                                         </code>
<code class="CodeIndent">| company_id - The primary key to company </code>
<code class="CodeIndent">| start_date - Start date used for date range </code>
<code class="CodeIndent">| end_date - End date for date range       </code>
<code class="CodeIndent">===========================================================</code>
<code class="CodeIndent">*/</code>
</pre>
<p class="BodyKeep">I like to use the following format for my block comments:
<pre><code class="CodeIndent">/*</code>
<code class="CodeIndent">|| I put the slash-asterisk that starts the comment on a line all by</code>
<code class="CodeIndent">|| itself. Then I start each line in the comment block with a double</code>
</pre>
<p class="CodeIndentKeep">|| vertical bar to highlight the presence of the comment. Finally,
<p class="CodeIndentKeep">|| I place the asterisk-slash on a line all by itself.
<pre><code class="CodeIndent">*/</code>
</pre>
<p class="Body">On the negative side, the vertical bars have to be erased whenever I reformat the lines, but that isn't too much of an effort. On the positive side, those vertical bars make it very easy for a programmer who is scanning the left side of the code to pick out the comments.
<p class="Body">I put the comment markers on their own lines to increase the whitespace in my program and set off the comment. That way I can avoid "heavy" horizontal lines full of delimiters, such as asterisks or dashes, and avoid having to match the longest line in the comment.
<h3 class="HeadB">Maintain Indentation</h3>
<p class="Body">Inline commentary should reinforce the indentation and therefore the logical structure of the program. For example, it is very easy to find the comments in the make_array procedures shown below. I do not use any double-hyphens, so the slash-asterisk sequences stand out nicely. In addition, all comments start in the first column, so I can easily scan down the left-hand side of the program and pick out the documentation:
<pre><code class="CodeIndent">PROCEDURE make_array (num_rows_in IN INTEGER) </code>
<code class="CodeIndent">/* Create an array of specified numbers of rows */</code>
<code class="CodeIndent">IS</code>
<code class="CodeIndent">/* Handles to Oracle Forms structures */</code>
<code class="CodeIndent">   col_id GROUPCOLUMN;</code>
<code class="CodeIndent">   rg_id RECORDGROUP;</code>
<code class="CodeIndent">BEGIN</code>
<code class="CodeIndent">/* Create new record group and column */</code>
<code class="CodeIndent">   rg_id := CREATE_GROUP ('array');</code>
<code class="CodeIndent">   col_id := ADD_GROUP_COLUMN ('col');</code>
<code class="CodeIndent">/* </code>
<code class="CodeIndent">|| Use a loop to create the specified number of rows and </code>
<code class="CodeIndent">|| set the value in each cell.</code>
<code class="CodeIndent">*/</code>
<code class="CodeIndent">   FOR row_index IN 1 .. num_rows_in</code>
<code class="CodeIndent">   LOOP</code>
<code class="CodeIndent">/* Create a row at the end of the group to accept data */</code>
<code class="CodeIndent">      ADD_GROUP_ROW (return_value, END_OF_GROUP);</code>
<code class="CodeIndent">      FOR col_index IN 1 .. num_columns_in</code>
<code class="CodeIndent">      LOOP</code>
<code class="CodeIndent">/* Set the initial value in the cell */</code>
<code class="CodeIndent">         SET_GROUP_NUMBER_CELL (col_id, row_index, 0); </code>
</pre>
<p class="CodeIndentKeep">END LOOP;
<pre><code class="CodeIndent">   END LOOP;</code>
<code class="CodeIndent">END;</code>
</pre>
<p class="Body">The problem with these comments is precisely that they do all start in the first column, regardless of the code they describe. The most glaring example of this formatting "disconnect" comes in the inner loop, repeated below:
<pre><code class="CodeIndent">      FOR col_index IN 1 .. num_columns_in</code>
<code class="CodeIndent">      LOOP</code>
<code class="CodeIndent">/* Set the initial value in the cell */</code>
<code class="CodeIndent">         SET_GROUP_NUMBER_CELL (col_id, row_index, 0); </code>
<code class="CodeIndent">      END LOOP;</code>
</pre>
<p class="Body">Your eye follows the three-space indentation very smoothly into the loop and then you are forced to move all the way to the left to pick up the comment. This format disrupts your reading of the code and therefore its readability. The code loses some of its ability to communicate the logical flow "at a glance," because the physical sense of indentation as logical flow is marred by the comments. Finally, you may end up writing full-line comments which are much longer than the code they appear next to, further distorting the code.
<p class="Body">Your comments should always be indented at the same level as the code which they describe. Assuming the comments come before the code itself, those lines of descriptive text will initiate the indentation at that logical level, which will also reinforce that structure. The make_array procedure, properly indented, is shown below:
<pre><code class="CodeIndent">PROCEDURE make_array (num_rows_in IN INTEGER) </code>
<code class="CodeIndent">/* Create an array of specified numbers of rows */</code>
<code class="CodeIndent">IS</code>
<code class="CodeIndent">   /* Handles to Oracle Forms structures */</code>
<code class="CodeIndent">   col_id GROUPCOLUMN;</code>
<code class="CodeIndent">   rg_id RECORDGROUP;</code>
<code class="CodeIndent">BEGIN</code>
<code class="CodeIndent">   /* Create new record group and column */</code>
<code class="CodeIndent">   rg_id := CREATE_GROUP ('array');</code>
<code class="CodeIndent">   col_id := ADD_GROUP_COLUMN ('col');</code>
<code class="CodeIndent">   /* </code>
<code class="CodeIndent">   || Use a loop to create the specified number of rows and </code>
<code class="CodeIndent">   || set the value in each cell.</code>
<code class="CodeIndent">   */</code>
<code class="CodeIndent">   FOR row_index IN 1 .. num_rows_in</code>
<code class="CodeIndent">   LOOP</code>
<code class="CodeIndent">      /* Create a row at the end of the group to accept data */</code>
<code class="CodeIndent">      ADD_GROUP_ROW (return_value, END_OF_GROUP);</code>
<code class="CodeIndent">      FOR col_index IN 1 .. num_columns_in</code>
<code class="CodeIndent">      LOOP</code>
<code class="CodeIndent">         /* Set the initial value in the cell */</code>
<code class="CodeIndent">         SET_GROUP_NUMBER_CELL (col_id, row_index, 0); </code>
</pre>
<p class="CodeIndentKeep">END LOOP;
<p class="CodeIndentKeep">END LOOP;
<pre><code class="CodeIndent">END;</code>
</pre>
<h3 class="HeadB">Comment Declaration Statements</h3>
<p class="BodyKeep">I propose the following simple rule for documenting declaration statements:
<blockquote class="ListSimple"><em class="Emphasis">Provide a comment for each and every declaration</em>.</blockquote>
<p class="Body">Does that sound excessive? Well, I must admit that I do not follow this guideline at all times, but I bet people who read my code wish I had. The declaration of a variable which seems to me to be perfectly clear may be a source of abiding confusion for others. Like many other people, I still have difficulty understanding that what is obvious to me is not necessarily obvious to someone else. </p>
<p class="Body">Consider the declaration section in the next example. The commenting style is inconsistent. I use double-hyphens for a two-line comment; then I use the standard block format to provide information about three variables all at once. I provide comments for some variables, but not for others. It's hard to make sense of the various declaration statements:</p>
<pre><code class="CodeIndent">DECLARE</code>
<code class="CodeIndent">   -- Assume a maximum string length of 1000 for a line of text.</code>
<code class="CodeIndent">   text_line VARCHAR2 (1000);</code>
<code class="CodeIndent">   len_text    NUMBER;</code>
<code class="CodeIndent">   /*</code>
<code class="CodeIndent">   || Variables used to keep track of string scan:</code>
<code class="CodeIndent">   ||    atomic_count - running count of atomics scanned.</code>
<code class="CodeIndent">   ||    still_scanning - Boolean variable controls WHILE loop.</code>
<code class="CodeIndent">   */</code>
<code class="CodeIndent">   atomic_count NUMBER := 1;</code>
<code class="CodeIndent">   still_scanning BOOLEAN;</code>
<code class="CodeIndent">BEGIN</code>
</pre>
<p class="Body">Let's recast this declaration section using my proposed guideline: a comment for each declaration statement. In the result shown below, the declaration section is now longer than the first version, but it uses whitespace more effectively. Each declaration has its own comment, set off by a blank line if a single-line comment:</p>
<pre><code class="CodeIndent">DECLARE</code>
<code class="CodeIndent">   /* Assume a maximum string length of 1000 for a line of text. */</code>
<code class="CodeIndent">   text_line VARCHAR2 (1000);</code>
<code class="CodeIndent">&nbsp;</code>
<code class="CodeIndent">   /* Calculate length of string at time of declaration */</code>
<code class="CodeIndent">   len_string NUMBER;</code>
<code class="CodeIndent">&nbsp;</code>
<code class="CodeIndent">   /* Running count of number of atomics scanned */</code>
<code class="CodeIndent">   atomic_count NUMBER := 1;</code>
<code class="CodeIndent">&nbsp;</code>
<code class="CodeIndent">   /* Boolean variable that controls WHILE loop */</code>
<code class="CodeIndent">   still_scanning BOOLEAN ;</code>
<code class="CodeIndent">BEGIN</code></pre>
<img src ="http://www.blogjava.net/Javawind/aggbug/203343.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Javawind/" target="_blank">kooyee</a> 2008-05-27 22:28 <a href="http://www.blogjava.net/Javawind/archive/2008/05/27/203343.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Oracle]each row and table level triggers</title><link>http://www.blogjava.net/Javawind/archive/2008/04/05/190965.html</link><dc:creator>kooyee</dc:creator><author>kooyee</author><pubDate>Sat, 05 Apr 2008 11:36:00 GMT</pubDate><guid>http://www.blogjava.net/Javawind/archive/2008/04/05/190965.html</guid><wfw:comment>http://www.blogjava.net/Javawind/comments/190965.html</wfw:comment><comments>http://www.blogjava.net/Javawind/archive/2008/04/05/190965.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Javawind/comments/commentRss/190965.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Javawind/services/trackbacks/190965.html</trackback:ping><description><![CDATA[row&nbsp; level triggers : 是每个row改变时，触发trigger。 比如，２个row update，触发２次。<br />
<br />
table level triggers: 是table改变时，触发trigger。无论几个row改变都没影响, 比如，1个row update触发1次 ,２个row update，也触发1次。<br />
<br />
顺便转个教程<br />
<h2 id="bef_er">Before / for each row trigger</h2>
<div class="txt">A before trigger is called <em>before</em> because it fires before the new values (<code>:new.field_name</code>) are stored in the table. That means that the new value can be changed in the trigger. </div>
<div>
<pre class="code"><a href="http://www.adp-gmbh.ch/ora/sql/create_table.html">create table</a> t_update_before_each_row (
txt varchar2(10)
);
create table log (
txt varchar2(20)
);
<a href="http://www.adp-gmbh.ch/ora/sql/create_trigger.html">create trigger</a> update_before_each_row
<strong>before update</strong> on t_update_before_each_row
<strong>for each row</strong>
<a href="http://www.adp-gmbh.ch/ora/plsql/block.html">begin</a>
:new.txt := upper(:new.txt);
insert into log values ('old: ' || :old.txt);
insert into log values ('new: ' || :new.txt);
<a href="http://www.adp-gmbh.ch/ora/plsql/block.html">end</a> update_before_each_row;
/
</pre>
</div>
<div>
<pre class="code">insert into t_update_before_each_row values('one');
insert into t_update_before_each_row values('two');
insert into t_update_before_each_row values('three');
insert into t_update_before_each_row values('four');
</pre>
</div>
<div class="txt">Updating (that is: concatenating the value with itself) the rows containing <em>two</em> and <em>three</em>: </div>
<div>
<pre class="code">update t_update_before_each_row set txt = txt || txt
where <a href="http://www.adp-gmbh.ch/ora/sql/substr.html">substr</a>(txt,1,1) = 't';
</pre>
</div>
<div>
<pre class="code"><a href="http://www.adp-gmbh.ch/ora/sql/select.html">select</a> * from t_update_before_each_row;
</pre>
</div>
<div class="txt">As can be seen by the output of the select statement, the trigger changed the values of the new values; they're in uppercase now: </div>
<div>
<pre class="out">one
TWOTWO
THREETHREE
four
</pre>
</div>
<div class="txt">The log displays the old and new values: </div>
<div>
<pre class="code"><a href="http://www.adp-gmbh.ch/ora/sql/select.html">select</a> * from log;
</pre>
</div>
<div>
<pre class="out">old: two
new: TWOTWO
old: three
new: THREETHREE
</pre>
</div>
<div class="txt">Cleaning up: </div>
<div>
<pre class="code">drop table t_update_before_each_row;
drop table log;
</pre>
</div>
<h2>After / for each row trigger</h2>
<div class="txt">In contrast to a before trigger, an after trigger does not allow to change <code>:new.field_name</code> because the value is, when the trigger fires, already written to the table. </div>
<div class="txt">If one tries to assign a value to <code>:new.field_name</code>, Oracle throws an <strong>ORA-04084: cannot change NEW values for this trigger type</strong>. </div>
<div>
<pre class="code">create table t_update_after_each_row (
txt varchar2(10)
);
create table log (
txt varchar2(20)
);
create trigger update_after_each_row
<strong>after</strong> update on t_update_after_each_row
<strong>for each row</strong>
begin
-- :new.txt := upper(:old.txt); -- <strong>ORA-04084</strong>: cannot change NEW values for this trigger type
insert into log values ('old: ' || :old.txt);
insert into log values ('new: ' || :new.txt);
end update_after_each_row;
/
</pre>
</div>
<div>
<pre class="code">insert into t_update_after_each_row values('one');
insert into t_update_after_each_row values('two');
insert into t_update_after_each_row values('three');
insert into t_update_after_each_row values('four');
</pre>
</div>
<div>
<pre class="code">update t_update_after_each_row set txt = txt || txt
where substr(txt,1,1) = 't';
</pre>
</div>
<div>
<pre class="code">select * from t_update_after_each_row;
</pre>
</div>
<div>
<pre class="out">one
twotwo
threethree
four
</pre>
</div>
<div>
<pre class="code">select * from log;
</pre>
</div>
<div class="txt">As the log table shows, it is possible to use <code>:new</code> and <code>:old</code> although it's not possible to assign something to <code>:new</code>. </div>
<div>
<pre class="out">old: two
new: twotwo
old: three
new: threethree
</pre>
</div>
<div class="txt">Cleaning up: </div>
<div>
<pre class="code">drop table t_update_after_each_row;
drop table log;
</pre>
</div>
<h2>Table level trigger</h2>
<div class="txt">A table level trigger is a trigger that doesn't fire for each row to be changed. Accordingly, it lacks the <code>for each row</code>. Consequently, both, the <code>:new</code> and <code>:old</code> are not permitted in the trigger's <a href="http://www.adp-gmbh.ch/ora/plsql/block.html">PL/SQL block</a>, otherwise, an <strong>ORA-04082: NEW or OLD references not allowed in table level triggers</strong> is thrown. </div>
<div>
<pre class="code">create table t_update_before (
txt varchar2(10)
);
create table log (
txt varchar2(20)
);
create trigger update_before
before update on t_update_before
begin
-- :new.txt := upper(:old.txt); -- <strong>ORA-04082</strong>
insert into log values ('update trigger');
end update_before;
/
</pre>
</div>
<div>
<pre class="code">insert into t_update_before values('one');
insert into t_update_before values('two');
insert into t_update_before values('three');
insert into t_update_before values('four');
</pre>
</div>
<div>
<pre class="code">update t_update_before set txt = txt || txt
where substr(txt,1,1) = 't';
</pre>
</div>
<div>
<pre class="code">select * from t_update_before;
</pre>
</div>
<div>
<pre class="out"><em>one
twotwo
threethree
four</em>
</pre>
</div>
<div class="txt">Although two rows were updated, only one record is found in the log table: </div>
<div>
<pre class="out">select * from log;
</pre>
</div>
<div>
<pre class="out">update trigger
</pre>
</div>
<div class="txt">An update statement that doesn't update any row: </div>
<div>
<pre class="code">update t_update_before set txt = txt || txt
where txt = 'no update';
</pre>
</div>
<div class="txt">Still, the trigger fires... </div>
<div>
<pre class="code">select * from log;
</pre>
</div>
<div class="txt">... which results in another row found in the log table: </div>
<div>
<pre class="out">update trigger
update trigger
</pre>
</div>
<div class="txt">Cleaning up: </div>
<div>
<pre class="code">drop table t_update_before;
drop table log;
</pre>
</div>
<h2>Order of execution</h2>
<div class="txt">Oracle allows to create multiple triggers on the same table. The order of the execution of these triggers is undeterministic (or random, if you want this word) except that all before triggers fire before the after triggers. </div>
<img src ="http://www.blogjava.net/Javawind/aggbug/190965.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Javawind/" target="_blank">kooyee</a> 2008-04-05 19:36 <a href="http://www.blogjava.net/Javawind/archive/2008/04/05/190965.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[MYSQL] SQLException: No suitable driver</title><link>http://www.blogjava.net/Javawind/archive/2007/11/16/161111.html</link><dc:creator>kooyee</dc:creator><author>kooyee</author><pubDate>Fri, 16 Nov 2007 12:33:00 GMT</pubDate><guid>http://www.blogjava.net/Javawind/archive/2007/11/16/161111.html</guid><wfw:comment>http://www.blogjava.net/Javawind/comments/161111.html</wfw:comment><comments>http://www.blogjava.net/Javawind/archive/2007/11/16/161111.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Javawind/comments/commentRss/161111.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Javawind/services/trackbacks/161111.html</trackback:ping><description><![CDATA[<p>问题可能是 建立database连接时，url的格式不正确引起的。<br />
<br />
正确格式为 </p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee" twffan="done"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" twffan="done"  alt="" /><span style="color: #000000" twffan="done">jdbc:mysql:</span><span style="color: #008000" twffan="done">//</span><span style="color: #008000" twffan="done">localhost : 3306/database</span></div>
<img src ="http://www.blogjava.net/Javawind/aggbug/161111.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Javawind/" target="_blank">kooyee</a> 2007-11-16 20:33 <a href="http://www.blogjava.net/Javawind/archive/2007/11/16/161111.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MySQL 5.1参考手册</title><link>http://www.blogjava.net/Javawind/archive/2007/11/10/159615.html</link><dc:creator>kooyee</dc:creator><author>kooyee</author><pubDate>Sat, 10 Nov 2007 13:00:00 GMT</pubDate><guid>http://www.blogjava.net/Javawind/archive/2007/11/10/159615.html</guid><wfw:comment>http://www.blogjava.net/Javawind/comments/159615.html</wfw:comment><comments>http://www.blogjava.net/Javawind/archive/2007/11/10/159615.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/Javawind/comments/commentRss/159615.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Javawind/services/trackbacks/159615.html</trackback:ping><description><![CDATA[http://dev.mysql.com/doc/refman/5.1/zh/index.html<br />
<br />
<div class="titlepage">
<div>
<div>
<h2 class="title"><a name="user-account-management"></a>5.8.&nbsp;MySQL用户账户管理</h2>
</div>
</div>
</div>
<div class="toc">
<dl>
<dt><span class="section"><a href="http://dev.mysql.com/doc/refman/5.1/zh/database-administration.html#user-names">5.8.1. MySQL用户名和密码</a></span>
<dt><span class="section"><a href="http://dev.mysql.com/doc/refman/5.1/zh/database-administration.html#adding-users">5.8.2. 向MySQL增加新用户账户</a></span>
<dt><span class="section"><a href="http://dev.mysql.com/doc/refman/5.1/zh/database-administration.html#removing-users">5.8.3. 从MySQL删除用户账户</a></span>
<dt><span class="section"><a href="http://dev.mysql.com/doc/refman/5.1/zh/database-administration.html#user-resources">5.8.4. 限制账户资源</a></span>
<dt><span class="section"><a href="http://dev.mysql.com/doc/refman/5.1/zh/database-administration.html#passwords">5.8.5. 设置账户密码</a></span>
<dt><span class="section"><a href="http://dev.mysql.com/doc/refman/5.1/zh/database-administration.html#password-security">5.8.6. 使你的密码安全</a></span>
<dt><span class="section"><a href="http://dev.mysql.com/doc/refman/5.1/zh/database-administration.html#secure-connections">5.8.7. 使用安全连接</a></span></dt></dl></div>
<br />
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="adding-users"></a>5.8.2.&nbsp;向MySQL增加新用户账户</h3>
</div>
</div>
</div>
<a class="indexterm" name="id2774260"></a><a class="indexterm" name="id2774269"></a><a class="indexterm" name="id2774281"></a><a class="indexterm" name="id2774291"></a><a class="indexterm" name="id2774302"></a><a class="indexterm" name="id2774312"></a><a class="indexterm" name="id2774322"></a>
<p>可以用两种方式创建<span>MySQL</span>账户：</p>
<p><span>&#183;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>使用<span>GRANT</span>语句</p>
<p><span>&#183;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>直接操作<span>MySQL</span>授权表</p>
<p>最好的方法是使用<span>GRANT</span>语句，因为这样更精确，错误少。从<span>MySQL 3.22.11</span>起提供了<span>GRANT</span>；其语法见<a title="13.5.1.3.&nbsp;GRANT and REVOKE Syntax" href="http://dev.mysql.com/doc/refman/5.1/zh/sql-syntax.html#grant">13.5.1.3节，&#8220;GRANT和REVOKE语法&#8221;</a>。</p>
<p>创建账户的其它方法是使用<span>MySQL</span>账户管理功能的第三方程序。<span>phpMyAdmin</span>即是一个程序。</p>
<p>下面的示例说明如何使用<strong><span 宋体;?>MySQL</span></strong>客户端程序来设置新用户。假定按照<a title="2.9.3.&nbsp;Securing the Initial MySQL Accounts" href="http://dev.mysql.com/doc/refman/5.1/zh/installing.html#default-privileges">2.9.3节，&#8220;使初始MySQL账户安全&#8221;</a>描述的 默认值来设置权限。这说明为了更改，你必须以<span>MySQL </span><span>root</span>用户连接<span>MySQL</span>服务器，并且<span>root</span>账户必须有<span>mysql</span>数据库的<span>INSERT</span>权限和<span>RELOAD</span>管理权限。</p>
<p>首先，使用<strong><span 宋体;?>MySQL</span></strong>程序以<span>MySQL </span><span>root</span>用户来连接服务器：</p>
<pre><span>shell&gt; </span><span>MySQL<strong> --user=root </strong>MySQL</span></pre>
<p>如果你为<span>root</span>账户指定了密码，还需要为该<strong><span>MySQL</span></strong>命令和本节中的其它命令提供<span>--password</span>或<span>-p</span>选项。</p>
<p><span>以<span>root</span></span>连接到服务器上后，可以添加新账户。下面的语句使用<span>GRANT</span>来设置四个新账户：</p>
<pre><span>mysql&gt; </span><span><strong><span>GRANT ALL PRIVILEGES ON *.* TO 'monty'@'localhost'</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>IDENTIFIED BY 'some_pass' WITH GRANT OPTION;</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>GRANT ALL PRIVILEGES ON *.* TO 'monty'@'%'</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>IDENTIFIED BY 'some_pass' WITH GRANT OPTION;</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>GRANT RELOAD,PROCESS ON *.* TO 'admin'@'localhost';</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>GRANT USAGE ON *.* TO 'dummy'@'localhost';</span></strong></span></pre>
<p>用<span>GRANT</span>语句创建的账户有下面的属性：</p>
<p><span>&#183;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>其中两个账户有相同的用户名<span>monty</span>和密码<span>some_pass</span>。两个账户均为超级用户账户，具有完全的权限可以做任何事情。一个账户<span> (</span><span>'monty'@'localhost'</span><span>)</span>只用于从本机连接时。另一个账户<span>(</span><span>'monty'@'%'</span><span>)</span>可用于从其它主机连接。请注意<span>monty</span>的两个账户必须能从任何主机以<span>monty</span>连接。没有<span>localhost</span>账户，当<span>monty</span>从本机连接时，<strong><span>mysql_install_db</span></strong>创建的<span>localhost</span>的匿名用户账户将占先。结果是，<span>monty</span>将被视为匿名用户。原因是匿名用户账户的<span>Host</span>列值比<span>'monty'@'%'</span>账户更具体，这样在<span>user</span>表排序顺序中排在前面。<span>(</span><span>user</span>表排序的讨论参见<a title="5.7.5.&nbsp;Access Control, Stage 1: Connection Verification" href="http://dev.mysql.com/doc/refman/5.1/zh/database-administration.html#connection-access">5.7.5节，&#8220;访问控制, 阶段1：连接核实&#8221;</a>）<span>。 </span></p>
<p><span>&#183;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>一个账户有用户名<span>admin</span>，没有密码。该账户只用于从本机连接。授予了<span>RELOAD</span>和<span>PROCESS</span>管理权限。这些权限允许<span>admin</span>用户执行<strong><span>mysqladmin reload</span></strong>、<strong><span>mysqladmin refresh</span></strong>和<strong><span>mysqladmin flush-</span></strong><span><strong><em><span>xxx</span></em></strong></span>命令，以及<strong><span>mysqladmin processlist</span></strong>。未授予访问数据库的权限。你可以通过<span>GRANT</span>语句添加此类权限。</p>
<p><span>&#183;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>一个账户有用户名<span>dummy</span>，没有密码。该账户只用于从本机连接。未授予权限。通过<span>GRANT</span>语句中的<span>USAGE</span>权限，你可以创建账户而不授予任何权限。它可以将所有全局权限设为<span>'N'</span>。假定你将在以后将具体权限授予该账户。</p>
<p>除了<span>GRANT</span>，你可以直接用<span>INSERT</span>语句创建相同的账户，然后使用<span>FLUSH PRIVILEGES</span>告诉服务器重载授权表：</p>
<pre><span>shell&gt; </span><span><strong><span>mysql --user=root mysql</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>INSERT INTO user</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>VALUES('localhost','monty',PASSWORD('some_pass'),</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>INSERT INTO user</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>VALUES('%','monty',PASSWORD('some_pass'),</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>INSERT INTO user SET Host='localhost',User='admin',</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>Reload_priv='Y', Process_priv='Y';</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>INSERT INTO user (Host,User,Password)</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>VALUES('localhost','dummy','');</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>FLUSH PRIVILEGES;</span></strong></span></pre>
<p>当你用<span>INSERT</span>创建账户时使用<span>FLUSH PRIVILEGES</span>的原因是告诉服务器重读授权表。否则，只有重启服务器后更改方会被注意到。使用 <span>GRANT</span>，则不需要使用<span>FLUSH PRIVILEGES</span>。</p>
<p>用<span>INSERT</span>使用<span>PASSWORD()</span>函数是为了加密密码。<span>GRANT</span>语句为你加密密码，因此不需要<span>PASSWORD()</span>。</p>
<p><span>'Y'</span>值启用账户权限。对于<span>admin</span>账户，还可以使用更加可读的<span>INSERT</span>扩充的语法（使用<span>SET</span>）。</p>
<p>在为<span>dummy</span>账户的<span>INSERT</span>语句中，只有<span>user</span>表中的<span>Host</span>、<span>User</span>和<span>Password</span>列记录为指定的值。没有一个权限列为显式设置，因此<span>MySQL</span>将它们均指定为 默认值<span>'N'</span>。这样等同于<span>GRANT USAGE</span>的操作。</p>
<p>请注意要设置超级用户账户，只需要创建一个权限列设置为<span>'Y'</span>的<span>user</span>表条目。<span>user</span>表权限为全局权限，因此其它 授权表不再需要条目。</p>
<p>下面的例子创建<span>3</span>个账户，允许它们访问专用数据库。每个账户的用户名为<span>custom</span>，密码为<span><span>obscure</span>。</span></p>
<p>要想用<span>GRANT</span>创建账户，使用下面的语句：</p>
<pre><span>shell&gt; </span><span>MySQL<strong> --user=root </strong>MySQL</span></pre>
<pre><span>shell&gt; </span><span><strong><span>mysql --user=root mysql</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>ON bankaccount.*</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>TO 'custom'@'localhost'</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>IDENTIFIED BY 'obscure';</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>ON expenses.*</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>TO 'custom'@'whitehouse.gov'</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>IDENTIFIED BY 'obscure';</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>ON customer.*</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>TO 'custom'@'server.domain'</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>IDENTIFIED BY 'obscure';</span></strong></span></pre>
<p>这<span>3</span>个账户可以用于：</p>
<p><span>&#183;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>第<span>1</span>个账户可以访问<span>bankaccount</span>数据库，但只能从本机访问。</p>
<p><span>&#183;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>第<span>2</span>个账户可以访问<span>expenses</span>数据库，但只能从主机<span>whitehouse.gov</span>访问。</p>
<p><span>&#183;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>第<span>3</span>个账户可以访问<span>customer</span>数据库，但只能从主机<span>server.domain</span>访问。</p>
<p>要想不用<span>GRANT</span>设置<span>custom</span>账户，使用<span>INSERT</span>语句直接修改 授权表：</p>
<pre><span>shell&gt; </span><span><strong><span>mysql --user=root mysql</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>INSERT INTO user (Host,User,Password)</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>VALUES('localhost','custom',PASSWORD('obscure'));</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>INSERT INTO user (Host,User,Password)</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>VALUES('whitehouse.gov','custom',PASSWORD('obscure'));</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>INSERT INTO user (Host,User,Password)</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>VALUES('server.domain','custom',PASSWORD('obscure'));</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>INSERT INTO db</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>(Host,Db,User,Select_priv,Insert_priv,</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>Update_priv,Delete_priv,Create_priv,Drop_priv)</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>VALUES('localhost','bankaccount','custom',</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>'Y','Y','Y','Y','Y','Y');</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>INSERT INTO db</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>(Host,Db,User,Select_priv,Insert_priv,</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>Update_priv,Delete_priv,Create_priv,Drop_priv)</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>VALUES('whitehouse.gov','expenses','custom',</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>'Y','Y','Y','Y','Y','Y');</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>INSERT INTO db</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>(Host,Db,User,Select_priv,Insert_priv,</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>Update_priv,Delete_priv,Create_priv,Drop_priv)</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>VALUES('server.domain','customer','custom',</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>'Y','Y','Y','Y','Y','Y');</span></strong></span></pre>
<pre><span>mysql&gt; </span><span><strong><span>FLUSH PRIVILEGES;</span></strong></span></pre>
<pre><span>&nbsp;</span></pre>
<p>前<span>3</span>个<span>INSERT</span>语句在<span>user</span>表中加入条目，允许用户<span>custom</span>从各种主机用给定的密码进行连接，但不授予全局权限<span>(</span>所有权限设置为 默认值<span>'N'</span><span>)</span>。后面<span>3</span>个<span>INSERT</span>语句在<span>user</span>表中加入条目，为<span>custom</span>授予<span>bankaccount</span>、<span>expenses</span>和<span>customer</span>数据库权限，但只能从合适的主机访问。<span>通常若直接修改 授权表，则应告诉服务器用</span><span>FLUSH PRIVILEGES</span><span>重载授权表，使权限更改生效。</span></p>
<p><span>如果你想要让某个用户从给定域的所有机器访问<span>(</span>例如，</span><span>mydomain.com</span><span>)</span><span>，你可以在账户名的主机部分使用含&#8216;</span><span>%</span><span>&#8217;通配符的</span><span>GRANT</span><span>语句：</span></p>
<pre><span>mysql&gt; </span><span><strong><span>GRANT ...</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>ON *.*</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>TO 'myname'@'%.mydomain.com'</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>IDENTIFIED BY 'mypass';</span></strong></span></pre>
<p>要想通过直接修改授权表来实现：</p>
<pre><span>mysql&gt; </span><span><strong><span>INSERT INTO user (Host,User,Password,...)</span></strong></span></pre>
<pre><span>&nbsp;&nbsp;&nbsp; -&gt;&nbsp;&nbsp;&nbsp;&nbsp; </span><span><strong><span>VALUES('%.mydomain.com','myname',PASSWORD('mypass'),...);</span></strong></span></pre>
<p><span>mysql&gt; </span><span><strong><span>FLUSH PRIVILEGES;</span></strong></span></p>
<img src ="http://www.blogjava.net/Javawind/aggbug/159615.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Javawind/" target="_blank">kooyee</a> 2007-11-10 21:00 <a href="http://www.blogjava.net/Javawind/archive/2007/11/10/159615.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>