Showing posts with label Database. Show all posts
Showing posts with label Database. Show all posts

Wednesday, August 25, 2010

Writing MySQL Scripts with PHP and PDO

Writing MySQL Scripts with PHP and PDO

Paul DuBois
paul@kitebird.com

Document revision: 1.01
Last update: 2008-05-07

Table of Contents


PHP makes it easy to write scripts that access databases, enabling you to create dynamic web pages that incorporate database content. PHP includes several specialized database-access interfaces that take the form of separate sets of functions for each database system. There is one set for MySQL, another for InterBase, another for PostgreSQL, and so forth. However, having a different set of functions for each database makes PHP scripts non-portable at the lexical (source code) level. For example, the function for issuing an SQL statement is named mysql_query(), ibase_query(), or pg_exec(), depending on whether you are using MySQL, InterBase, or PostgreSQL.

In PHP 5 and up, you can avoid this problem by using the PHP Data Objects (PDO) extension. PDO supports database access in an engine-independent manner based on a two-level architecture:

  • The top level provides an interface that consists of a set of classes and methods that is the same for all database engines supported by PDO. The interface hides engine-specific details so that script writers need not think about which set of functions to use.
  • The lower level consists of individual drivers. Each driver supports a particular database engine and translates between the top-level interface seen by script writers and the database-specific interface required by the engine. This provides you the flexibility of using any database for which a driver exists, without having to consider driver-specific details.
This architectural approach has been used successfully with other languages--for example, to develop the DBI (Perl, Ruby), DB-API (Python), and JDBC (Java) database access interfaces. It's also been used with PHP before: PHPLIB, MetaBase, and PEAR DB are other packages that provide a uniform database-independent interface across different engines.

I have written elsewhere about using the PEAR DB module for writing PHP scripts that perform database processing in an engine-independent manner (see "Resources"). This document is similar but covers PDO instead. The examples use the driver for MySQL.

Preliminary Requirements


PDO uses object-oriented features available only in PHP 5 and up, so you must have PHP 5 or newer installed to use PDO for writing scripts that access MySQL.

PDO uses classes and objects to present an object-oriented interface. This article assumes that you are familiar with PHP's approach to object-oriented programming. If you are not, you may wish to review the "Classes and Objects" chapter of the PHP Manual.

Writing PDO Scripts


Scripts that use the PDO interface to access MySQL generally perform the following operations:

  • Connect to the MySQL server by calling new PDO() to obtain a database handle object.
  • Use the database handle to issue SQL statements or obtain statement handle objects.
  • Use the database and statement handles to retrieve information returned by the statements.
  • Disconnect from the server when the database handle is no longer needed.
The next sections discuss these operations in more detail.

Connecting to and Disconnecting from the MySQL Server


To establish a connection to a MySQL server, specify a data source name (DSN) containing connection parameters, and optionally the username and password of the MySQL account that you want to use. To connect to the MySQL server on the local host to access the test database with a username and password of testuser and testpass, the connection sequence looks like this:

   $dbh = new PDO("mysql:host=localhost;dbname=test", "testuser", "testpass");
For MySQL, the DSN is a string that indicates the database driver (mysql), and optionally the hostname where the server is running and the name of the database you want to use. Typical syntax for the DSN looks like this:
   mysql:host=host_name;dbname=db_name
The default host is localhost. No default database is selected if dbname is omitted.

The MySQL driver also recognizes port and unix_socket parameters, which specify the TCP/IP port number and Unix socket file pathname, respectively. If you use unix_socket, do not specify host or port.

For other database engines, the driver name is different (for example, pgsql for PostgreSQL) and the parameters following the colon might be different as well.

When you invoke the new PDO() constructor method to connect to your database server, PDO determines from the DSN which type of database engine you want to use and acesses the low-level driver appropriate for that engine. This is similar to the way that Perl or Ruby DBI scripts reference only the top-level DBI module; the connect() method provided by the top-level module looks at the DSN and determines which particular lower-level driver to use.

If new PDO() fails, PHP throws an exception. Otherwise, the constructor method returns an object of the PDO class. This object is a database handle that you use for interacting with the database server until you close the connection.

An alternative to putting the connection code directly in your script is to move it into a separate file that you reference from your main script. For example, you could create a file pdo_testdb_connect.php that looks like this:

     # pdo_testdb_connect.php - function for connecting to the "test" database

function testdb_connect ()
{
$dbh = new PDO("mysql:host=localhost;dbname=test", "testuser", "testpass");
return ($dbh);
}
?>
Then include the file into your main script and call testdb_connect() to connect and obtain the database handle:
   require_once "pdo_testdb_connect.php";

$dbh = testdb_connect ();
This approach makes it easier to use the same connection parameters in several different scripts without writing the values literally into every script; if you need to change a parameter sometime, just change pdo_testdb_connect.php. Use of a separate file also enables you to move the code that contains the connection parameters outside of the web server's document tree. That has the benefit of preventing it from being displayed literally if the server becomes misconfigured and starts serving PHP scripts as plain text.

Any of the PHP file-inclusion statements can be used, such as include or require, but require_once prevents errors from occurring if any other files that your script uses also reference pdo_testdb_connect.php.

When you're done using the connection, close it by setting the database handle to NULL:

   $dbh = NULL;
After that, $dbh becomes invalid as a database handle and can no longer be used as such.

If you do not close the connection explicitly, PHP does so when the script terminates.

While the database handle is open and you are using it to issue other PDO calls, you should arrange to handle errors if they occur. You can check for an error after each PDO call, or you can cause exceptions to be thrown. The latter approach is simpler because you need not check for errors explicitly; any error raises an exception that terminates your script. If you enable exceptions, you also have the option of catching them yourself instead of allowing them to terminate your script. By doing this, you can substitute your own error messages for the defaults, perform cleanup operations, and so on.

To enable exceptions, set the PDO error mode as follows after connecting:

   $dbh->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
That statement is something you could add to the testdb_connect() function if you want the error mode to be set automatically whenever you connect.

For more information on dealing with errors, see "Handling Errors."

Issuing Statements


After obtaining a database handle by calling new PDO(), you can use it to execute SQL statements:

  • For statements that modify rows and produce no result set, pass the statement string to the database handle exec() method, which executes the statement and returns an affected-rows count:
       $count = $dbh->exec ("some SQL statement");
  • For statements that select rows and produce a result set, invoke the database handle query() method, which executes the statement and returns an object of the PDOStatement class:
       $sth = $dbh->query ("some SQL statement");
    This object is a statement handle that provides access to the result set. It enables you to fetch the result set rows and obtain metadata about them, such as the number of columns.
To illustrate how to handle various types of statements, the following discussion shows how to create and populate a table using CREATE TABLE and INSERT (statements that return no result set). Then it uses SELECT to generate a result set.
Issuing Statements That Return No Result Set

The following code uses the database handle exec() method to issue a statement that creates a simple table animal with two columns, name and category:

   $dbh->exec ("CREATE TABLE animal (name CHAR(40), category CHAR(40))");
After the table has been created, it can be populated. The following example invokes the exec() method to issue an INSERT statement that loads a small data set into the animal table:
   $count = $dbh->exec ("INSERT INTO animal (name, category)
VALUES
('snake', 'reptile'),
('frog', 'amphibian'),
('tuna', 'fish'),
('racoon', 'mammal')");
exec() returns a count to indicate how many rows were affected by the statement. For the preceding INSERT statement, the affected-rows count is 4.
Issuing Statements That Return a Result Set

Now that the table exists and contains a few records, SELECT can be used to retrieve rows from it. To issue statements that return a result set, use the database handle query() method:

   $sth = $dbh->query ("SELECT name, category FROM animal");
printf ("Number of columns in result set: %d\n", $sth->columnCount ());
$count = 0;
while ($row = $sth->fetch ())
{
printf ("Name: %s, Category: %s\n", $row[0], $row[1]);
$count++;
}
printf ("Number of rows in result set: %d\n", $count);
A successful query() call returns a PDOStatement statement-handle object that is used for all operations on the result set. Some of the information available from a PDOStatement object includes the row contents and the number of columns in the result set:
  • The fetch() method returns each row in succession, or FALSE when there are no more rows.
  • The columnCount() methods returns the number of columns in the result set.
Note: A statement handle also has a rowCount() method, but it cannot be assumed to reliably return the number of rows in the result set. Instead, fetch the rows and count them, as shown in the preceding example.
Other Ways To Fetch Result Set Rows

fetch() accepts an optional fetch-mode argument indicating what type of value to return. This section describes some common mode values. Assume in each case that the following query has just been issued to produce a result set:

   $sth = $dbh->query ("SELECT name, category FROM animal");
  • PDO::FETCH_NUM
    Return each row of the result set as an array containing elements that correspond to the columns named in the SELECT statement and that are accessed by numeric indices beginning at 0:
       while ($row = $sth->fetch (PDO::FETCH_NUM))
    printf ("Name: %s, Category: %s\n", $row[0], $row[1]);
  • PDO::FETCH_ASSOC
    Return each row as an array containing elements that are accessed by column name:
       while ($row = $sth->fetch (PDO::FETCH_ASSOC))
    printf ("Name: %s, Category: %s\n", $row["name"], $row["category"]);
  • PDO::FETCH_BOTH
    Return each row as an array containing elements that can be accessed either by numeric index or by column name:
       while ($row = $sth->fetch (PDO::FETCH_BOTH))
    {
    printf ("Name: %s, Category: %s\n", $row[0], $row[1]);
    printf ("Name: %s, Category: %s\n", $row["name"], $row["category"]);
    }
  • PDO::FETCH_OBJ
    Return each row as an object. In this case, you access column values as object properties that have the same names as columns in the result set:
       while ($row = $sth->fetch (PDO::FETCH_OBJ))
    printf ("Name: %s, Category: %s\n", $row->name, $row->category);
If you invoke fetch() with no argument, the default fetch mode is PDO::FETCH_BOTH unless you change the default before fetching the rows:
  • The query() method accepts an optional fetch-mode argument following the statement string:
       $sth = $dbh->query ("SELECT name, category FROM animal", PDO::FETCH_OBJ);
    while ($row = $sth->fetch ())
    printf ("Name: %s, Category: %s\n", $row->name, $row->category);
  • Statement handles have a setFetchMode() method to set the mode for subsequent fetch() calls:
       $sth->setFetchMode (PDO::FETCH_OBJ);
    while ($row = $sth->fetch ())
    printf ("Name: %s, Category: %s\n", $row->name, $row->category);
Another way to fetch results is to bind variables to the result set columns with bindColumn(). Then you fetch each row using the PDO::FETCH_BOUND fetch mode. PDO stores the column values in the variables, and fetch() returns TRUE instead of a row value while rows remain in the result set:
   $sth = $dbh->query ("SELECT name, category FROM animal");
$sth->bindColumn (1, $name);
$sth->bindColumn (2, $category);
while ($sth->fetch (PDO::FETCH_BOUND))
printf ("Name: %s, Category: %s\n", $name, $category);

Using Prepared Statements


exec() and query() are PDO object methods: You use them with a database handle and they execute a statement immediately and return its result. It is also possible to prepare a statement for execution without executing it immediately. The prepare() method takes an SQL statement as its argument and returns a PDOStatement statement-handle object. The statement handle has an execute() method that executes the statement:

   $sth = $dbh->prepare ($stmt);
$sth->execute ();
Following execution, other statement-handle methods provide information about the statement result:
  • For a statement that modifies rows, invoke rowCount() to get the rows-affected count:
       $sth = $dbh->prepare ("DELETE FROM animal WHERE category = 'mammal'");
    $sth->execute ();
    printf ("Number of rows affected: %d\n", $sth->rowCount ());
  • For a statement that produces a result set, the fetch() method retrieves them and the columnCount() method indicates how many columns there are. To determine how many rows there are, count them as you fetch them. (As mentioned previously, rowCount() returns a row count, but should be used only for statements that modify rows.)
       $sth = $dbh->prepare ("SELECT name, category FROM animal");
    $sth->execute ();
    printf ("Number of columns in result set: %d\n", $sth->columnCount ());
    $count = 0;
    while ($row = $sth->fetch ())
    {
    printf ("Name: %s, Category: %s\n", $row[0], $row[1]);
    $count++;
    }
    printf ("Number of rows in result set: %d\n", $count);
If you are not sure whether a given SQL statement modifies or returns nows, the statement handle itself enables you to determine the proper mode of processing. See "Determining the Type of a Statement."

As just shown, prepared statements appear to offer no advantage over exec() and query() because using them introduces an extra step into statement processing. But there are indeed some benefits to them:

  • Prepared statements can be parameterized with placeholders that indicate where data values should appear. You can bind specific values to these placeholders and PDO takes care of any quoting or escaping issues for values that contain special characters. "Placeholders and Quoting" discusses these topics further.
  • Separating statement preparation from execution can be more efficient for statements to be executed multiple times because the preparation phase need be done only once. For example, if you need to insert a bunch of rows, you can prepare an INSERT statement once and then execute it repeatedly, binding successive row values to it for each execution.

Placeholders and Quoting


A prepared statement can contain placeholders to indicate where data values should appear. After you prepare the statement, bind specific values to the placeholders (either before or at statement-execution time), and PDO substitutes the values into the statement before sending it to the database server.

PDO supports named and positional placeholders:

  • A named placeholder consists of a name preceded by a colon. After you prepare the statement, use bindValue() to provide a value for each placeholder, and then execute the statement. To insert another row, bind new values to the placeholders and invoke execute() again:
       $sth = $dbh->prepare ("INSERT INTO animal (name, category)
    VALUES (:name, :cat)");
    $sth->bindValue (":name", "ant");
    $sth->bindValue (":cat", "insect");
    $sth->execute ();
    $sth->bindValue (":name", "snail");
    $sth->bindValue (":cat", "gastropod");
    $sth->execute ();
    As an alternative to binding the data values before calling execute(), you can pass the values directly to execute() using an array that associates placeholder names with the values:
       $sth->execute (array (":name" => "black widow", ":cat" => "spider"));
  • Positional placeholders are characters within the statement string. You can bind the values prior to calling execute(), similar to the previous example, or pass an array of values directly to execute():
       $sth = $dbh->prepare ("INSERT INTO animal (name, category)
    VALUES (?, ?)");
    # use bindValue() to bind data values
    $sth->bindValue (1, "ant");
    $sth->bindValue (2, "insect");
    $sth->execute ();
    # pass values directly to execute() as an array
    $sth->execute (array ("snail", "gastropod"));
Positional placeholder numbers begin with 1.

An alternative to bindValue() is bindParam(), which adds a level of indirection to value-binding. Instead of passing a data value as the second argument to bindParam(), pass a variable to associate the variable with the placeholder. To supply a value for the placeholder, assign a value to the variable:

   $sth = $dbh->prepare ("INSERT INTO animal (name, category)
VALUES (?, ?)");
$sth->bindParam (1, $name);
$sth->bindParam (2, $category);
$name = "ant";
$category = "insect";
$sth->execute ();
$name = "snail";
$category = "gastropod";
$sth->execute ();
The preceding examples use INSERT statements, but placeholder techniques are applicable to any type of statement, such as UPDATE or SELECT.

One of the benefits of using placeholders is that PDO handles any quoting or escaping of special characters or NULL values. For example, if you bind the string "a'b'c" to a placeholder, PDO inserts "'a\'b\'c'" into the statement. To bind the SQL NULL value to a placeholder, bind the PHP NULL value. In this case, PDO inserts the word "NULL" into the statement without surrounding quotes. (Were quotes to be added, the value inserted into the statement would be the string "'NULL'", which is incorrect.)

PDO also provides a database handle quote() method to which you can pass a string and receive back a quoted string with special characters escaped. However, I find this method deficient. For example, if you pass it NULL, it returns an empty string, which if inserted into a statement string does not correspond to the SQL NULL value. Use quote() with care if you use it.

Determining the Type of a Statement


When you issue a statement using a database handle, you must know whether the statement modifies rows or produces a result set, so that you can invoke whichever of exec() or query() is appropriate. However, under certain circumstances, you might not know the statement type, such as when you write a script to execute arbitrary statements that it reads from a file. To handle such cases, use prepare() with the database handle to get a statement handle and execute() to execute the statement. Then check the statement's column count:

  • If columnCount() is zero, the statement did not produce a result set. Instead, it modified rows and you can invoke rowCount() to determine the number of affected rows.
  • If columnCount() is greater than zero, the statement produced a result set and you can fetch the rows. To determine how many rows there are, count them as you fetch them.
The following example determines whether a statement modifies rows or produces a result set, and then processes it accordingly:
   $sth = $dbh->prepare ($stmt);
$sth->execute ();
if ($sth->columnCount () == 0)
{
# there is no result set, so the statement modifies rows
printf ("Number of rows affected: %d\n", $sth->rowCount ());
}
else
{
# there is a result set
printf ("Number of columns in result set: %d\n", $sth->columnCount ());
$count = 0;
while ($row = $sth->fetch (PDO::FETCH_NUM))
{
# display column values separated by commas
print (join (", ", $row) . "\n");
$count++;
}
printf ("Number of rows in result set: %d\n", $count);
}

Handling Errors


When you invoke new PDO() to create a database handle, occurrance of an error causes a PDOException to be thrown. If you don't catch the exception, PHP terminates your script. To handle the exception yourself, use a try block to perform the connection attempt and a catch block to catch any error that occurs:

   try
{
$dbh = new PDO("mysql:host=localhost;dbname=test", "testuser", "testpass");
}
catch (PDOException $e)
{
print ("Could not connect to server.\n");
print ("getMessage(): " . $e->getMessage () . "\n");
}
A PDOException is an extension of the PHP Exception class, so it has getCode() and getMessage() methods that return an error code and descriptive message, respectively. (However, I find that getCode() always returns 0 for connection errors and is meaningful only for PDO exceptions that occur after the connection has been established.)

After you successfully obtain a database handle, further PDO calls that use it are handled according to the PDO error mode. There are three modes:

  • PDO::ERRMODE_SILENT
    When an error occurs in silent or warning mode for a given object method, PDO sets up error information that you can access when the method returns. This is the default error mode.
  • PDO::ERRMODE_WARNING
    This is like silent mode but PDO also displays a warning message in addition to setting up error information when an error occurs.
  • PDO::ERRMODE_EXCEPTION
    PDO sets up error information when an error occurs and throws a PDOException.
PDO sets error information for the object to which the error applies, regardless of the error mode. This information is available via the object's errorCode() and errorInfo() methods. errorCode() returns an SQLSTATE value (a five-character string). errorInfo() returns a three-element array containing the SQLSTATE value, and a driver-specific error code and error message. For MySQL, the driver-specific values are a numeric error code and a descriptive error message.

To handle errors in silent mode, you must check the result of each PDO call. The following example shows how to test for errors during an operation that uses a database handle, $dbh, and a statement handle, $sth (you would not necessarily print all the available information as the example does):

   if (!($sth = $dbh->prepare ("INSERT INTO no_such_table")))
{
print ("Could not prepare statement.\n");
print ("errorCode: " . $dbh->errorCode () . "\n");
print ("errorInfo: " . join (", ", $dbh->errorInfo ()) . "\n");
}
else if (!$sth->execute ())
{
print ("Could not execute statement.\n");
print ("errorCode: " . $sth->errorCode () . "\n");
print ("errorInfo: " . join (", ", $sth->errorInfo ()) . "\n");
}
Testing the result of every call can become messy quickly. Another way to deal with failures is to set the error handling mode so that any error raises an exception:
   $dbh->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
In this case, you can assume that if you invoke a method and it returns, it succeeded. You can either leave exceptions uncaught or catch and handle them yourself. If you leave them uncaught, exceptions cause PHP to print a backtrace and terminate your script. To catch exceptions, perform PDO operations using a try/catch construct. The try block contains the operations and the catch block handles an execption if one occurs.
   try
{
$sth = $dbh->prepare ("INSERT INTO no_such_table");
$sth->execute ();
}
catch (PDOException $e)
{
print ("The statement failed.\n");
print ("getCode: ". $e->getCode () . "\n");
print ("getMessage: ". $e->getMessage () . "\n");
}
By using try and catch, you can substitute your own error messages if you like, perform cleanup operations, and so on.

As shown in the preceding example, the try block can contain operations on multiple handles. However, if an exception occurs in that case, you won't be able to use the handle-specific errorCode() or errorInfo() methods in the catch block very easily because you won't know which handle caused the error. You'll need to use the information available from the exception methods, as shown.

Using Transactions


In MySQL, some storage engines are transactional, which enables you to perform an operation and then commit it permanently if it succeeded or roll it back to cancel its effects if an error occurred. PDO provides a mechanism for performing transactions that is based on the following database-handle methods:

  • To start a transaction, invoke beginTransaction() to disable autocommit mode so that database changes do not take effect immediately.
  • To commit a successful transaction or roll back an unsuccessful one, invoke commit() or rollback(), respectively.
The easiest way to use these methods is to enable PDO exceptions and use try and catch to handle errors:
   $dbh->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try
{
$dbh->beginTransaction (); # start the transaction
# ... perform database operation ...
$dbh->commit (); # success
}
catch (PDOException $e)
{
print ("Transaction failed: " . $e->getMessage () . "\n");
$dbh->rollback (); # failure
}
For additional paranoia, you can place the rollback() call within a nested try/catch construct so that if rollback() itself fails and raises another exception, the script doesn't get terminated.

Resources


Revision History


  • 1.00--Original version.
  • 1.01, 2008-05-07--Removed my mistaken statement that the PDO driver for MySQL requires the mysqli extension. It does not. The driver uses libmysqlclient directly.

Monday, July 26, 2010

Bài 3 Đi lại trong XML bằng XPATH (phần II)

Đi lại trong XML bằng PATH (phần II)

Collections

Cái bộ (Set of) Nodes do XPath trả về được gọi là Collection. Thông thường trong lập trình, từ "Collection" được dùng để nói đến một tập hợp các objects đồng loại. Ta có thể lần lượt đi qua (iterate through) các objects trong một Collection nhưng không được bảo đảm thứ tự của chúng, tức là gặp object nào trước hay object nào sau.

Trái lại, trong chuẩn XPath, khi một Collection được trả về bởi một XPath Query (hỏi), nó giữ nguyên thứ tự các Nodes và cấp bậc của chúng trong tài liệu XML. Tức là nếu XPath trả về một cành các nodes thì trừ những nodes không thỏa điều kiện, các node còn lại vẫn giữ đúng vị trí trên cành.

Vì các Attributes của một Element không có thứ tự, nên chúng có thể nằm lộn xộn trong một Collection.

Indexing trong một Collection

Một Collection của Nodes được xem như một Array. Muốn nói trực tiếp đến một Node trong Collection ta có thể dùng một index trong cặp ngoặc vuông. Node thứ nhất có Index là 1.

Cặp ngoặc vuông ([]) có precedence cao hơn (được tính trước) dấu slash(/) hay hai dấu slash (//). Dưới đây là hai thí dụ:
ExpressionÝ nghĩa
author[1] Element author đầu tiên.
author[firstname][3] Element author thứ ba có mộtElement firstname con.

Mối liên hệ (Axes)

Một location path dùng một Axis để chỉ định mối liên hệ giữa các Nodes được chọn đối với context node. Sau đây là bảng liệt kê đầy đủ các axes:






















































AxesÝ nghĩa
ancestor::
Tổ tiên của context node.

Những tổ tiên của context node gồm có cha, ông nội, ông cố .v.v., do đó ancestor:: axis luôn luôn kể cả root node trừ khi chính context node là root node.

ancestor-or-self::
Chính context node và tổ tiên của nó.

Cái ancestor-or-self:: axis luôn luôn kể cả root node.

attribute::
Các Attributes của context node.

Nếu context node không phải là một Element thì chắc chắn axis sẽ trống rỗng.

child:: Con cái của context node.

Một con là bất cứ node nào nằm ngay dưới context node trong tree. Tuy nhiên, Attribute hay Namespace nodes không được xem là con cái của context node.

descendant::
Con cháu của context node.

Con cháu là con, cháu, chít, .v.v., do đó descendant:: axis không bao giờ chứa Attribute hay Namespace nodes.

following::
Mọi nodes hiện ra sau context node trên tree, không kể con cháu, Attribute nodes, hay Namespace nodes.
following-sibling::
Mọi nodes em (nằm sau) context node.

following-sibling:: axis nói đến chỉ những Nodes con, của cùng một Node cha, nằm trên tree sau context node. Axis không kể các Nodes anh nằm trước context node.

Nếu context node là Attribute hay Namespace thì following-sibling:: axis sẽ trống rỗng.

namespace:: Những Namespace nodes của context node.

Mỗi namespace có một namespace node trong scope (phạm vi hoạt động) của context node.

Nếu context node không phải là một Element thì Axis sẽ trống rỗng.

parent:: Node cha của context node, nếu nó có cha.

Node cha là node nằm ngay phía trên context node trên tree.

preceding::
Mọi nodes hiện ra trước context node trên tree, không kể các nodes tổ tiên, Attribute nodes, hay Namespace nodes.

Một cách để nhận diện preceding:: axis là mọi nodes đã kết thúc hoàn toàn trước khi context node bắt đầu.

preceding-sibling::
Mọi nodes anh (nằm trước) context node.

preceding-sibling:: axis nói đến chỉ những Nodes con, của cùng một Node cha, nằm trên tree trước context node.

Nếu context node là Attribute hay Namespace thì preceding-sibling:: axis sẽ trống rỗng.

self:: Là chính context node.

Sàng lọc (Filters)

Như ta đã thấy ở trên, để giới hạn chỉ lấy ra những Nodes thỏa đáng một điều kiện, ta gắn một Filter (sàng lọc) vào Collection. Filter ấy là một Clause giống giống Clause WHERE trong ngôn ngữ SQL của cơ sở dữ liệu.

Nếu một Collection nằm giữa một filter, nó sẽ cho kết quả TRUE nếu Collection trả về ít nhất một Node và FALSE nếu Collection trống rỗng (empty). Thí dụ expression author/degree có nghĩa rằng hàm biến đổi Collection ra trị số Boolean sẽ có giá trị TRUE nếu hiện hữa một Element author có Element con tên degree.

Filters luôn luôn được tính theo context của nó. Nói một cách khác, cái expression book[author] có nghĩa là cho mỗi Element book tìm thấy, nó sẽ được thử xem có chứa một Element con tên author không. Tương tự như vậy, book[author = 'Brown'] có nghĩa rằng cho mỗi Element book tìm thấy, nó sẽ được thử xem có chứa một Element con tên author với trị số bằng Brown không.

Ta có thể dùng dấu chấm (.) để khám current context node. Thí dụ như, book[. = 'Dreams'] có nghĩa rằng cho mỗi Element book tìm thấy trong current context, nó sẽ được thử xem có trị số bằng Dreams không. Dưới đây là một ít thí dụ:


























ExpressionÝ nghĩa
book[excerpt] Mọi Element book có chứa ít nhất một Element excerpt.
book[excerpt]/title Mọi Element title nằm trong những Element book có chứa ít nhất một Element excerpt.
book[excerpt]/author[degree]
Mọi Element author có chứa ít nhất một Element degree và nằm trong những Elements book có chứa ít nhất một Element excerpt.
book[author/degree] Mọi Element book có chứa ít nhất một Element author với ít nhất một Element degree con.
book[excerpt][title] Mọi Element book có chứa ít nhất một Element excerpt và ít nhất một Element title.

So sánh

Để so sánh hai objects trong XPath ta dùng dấu (=) cho bằng nhau và (!= ) cho không bằng nhau. Mọi Element và Attributes là string, nhưng được Typecast (xem như ) những con số khi đem ra so sánh.


























ExpressionÝ nghĩa
author[lastname = "Smith"]
Mọi Element author có chứa ít nhất một Element lastname với trị số bằng Smith.
author[lastname[1] = "Smith"]
Mọi Element author có Element lastname con đầu tiên với trị số bằng Smith.
author/degree[@from != "Harvard"]
Mọi Element degree, là con một Element author, và có một Attribute from với trị số không phải là "Harvard".
author[lastname = /editor/lastname]
Mọi Element author có chứa một Element lastname bằng với Element lastname là con của root Element editor.
author[. = "John Hamilton"]
Mọi Element author có trị số string là John Hamilton.

Operator Union | (họp lại)

Ngôn ngữ Xpath hỗ trợ Operator Union, giống như Logical OR (hoặc là). Dưới đây là vài thí dụ:






















ExpressionÝ nghĩa
firstname | lastname Mọi Element firstname lastname trong current context.
(bookstore/book | bookstore/magazine) Mọi Element book hay magazine là con một Element bookstore.
book | book/author Mọi Element book hay Element author là con những Elements book.
(book | magazine)/price Mọi Element price là con của Element book hay Element magazine.

Thử loại Node (Node Type Tests)

Để chọn những loại Node khác hơn là Element node, ta dùng Node-Type Test. Mục đích của việc dùng Node-Type test là để chỉ định sự lựa chọn khác thường. Thí dụ như, descendant::text() cho ta mọi text nodes là con cháu của context node, dù rằng loại node chính của con cháu context node là Element. Có 4 loại Node-Type tests như liệt kê dưới đây.



























Node typeTrả vềThí dụ
comment() mọi comment node.following::comment() chọn mọi comment nodes hiện ra sau context node.
node() mọi node.preceding::node() chọn mọi nodes hiện ra trước context node.
processing-instruction() mọi processing instruction node.self::processing instruction() chọn mọi processing instruction nodes trong context node.
text() mọi text node.child::text() chọn mọi text nodes là con của the context node.

Thử Node nhắm vào loại Processing Instruction

Một node test có thể chọn processing instruction thuộc loại nào, tức là chọn mục tiêu (target). Cú pháp của một loại test như thế là:





  processing-instruction("target")

Thí dụ node test sau đây trả về mọi processing instruction nodes có nhắc đến một XSL stylesheet trong tài liệu:





  /child::processing-instruction("xml-stylesheet")


Thêm một số thí dụ Location Path







































































































ExpressionÝ nghĩa
./author Mọi Element author trong current context.

Expresion nầy tương đương với expression trong hàng kế.
author Mọi Element author trong current context.
/bookstore Document (Root) Element tên bookstore của tài liệu nầy.
//author Mọi Element author trong tài liệu.
book[/bookstore/@specialty = @style]
Mọi Element book có Attribute style với value bằng value của Attribute specialty của Document Element bookstore của tài liệu.
author/firstname Mọi Element firstname con của các Elements author.
bookstore//title Mọi Element title một hay nhiều bậc thấp hơn, tức là con cháu của, Element bookstore. Lưu ý là expression nầy khác với expression trong hàng kế.
bookstore/*/title Mọi Element title cháu của các bookstore.
bookstore//book/excerpt//emph Mọi Element emph bất cứ nơi nào dưới excerpt là con của những elements book , bất cứ nơi nào dưới element bookstore.
.//title Mọi Element title một hay nhiều bậc thấp hơn current context node.
author/* Mọi Element là con của các elements con author.
book/*/lastname Mọi Element lastname là cháu của các elements con book.
*/* Mọi Element cháu của current context node.
*[@specialty] Mọi Element con có Attribute specialty.
@style Attribute style của current context node.
price/@exchange Attribute exchange của những Elements price trong current context, tức là những Elements price của current context node.
price/@exchange/total Trả về một node set trống rỗng, vì Attributes không có Element con. Expression nầy được chấp nhận trong văn phạm của XML Path Language, nhưng không thật sự hợp lệ.
book[@style] Mọi Element book có Attribute style trong current context node.
Lưu ý phần nằm trong ngoặc vuông là điều kiện của Element book
book/@style Attribute style của mọi Element booktrong current context node.

Ở đây không có điều kiện như hàng trên. Ta nói đến Attribute hay Element nằm bên phải nhất.
@* Mọi Attributes của current context node.
author[1] Element author thứ nhất trong
current context node.
author[firstname][3] Element author thứ ba có một
Element con firstname.
my:book Element book từ namespace my.
my:* Mọi Element trong namespace my.

Bài 2 Đi lại trong XML bằng XPATH (phần I)

Bài 2 Đi lại trong XML bằng XPATH (phần I)

Chúng ta đã thấy cấu trúc và cú pháp của XML tương đối đơn giãn. XML cho ta một cách chuẩn để trao đổi tin tức giữa các computers. Bước tiếp theo là tìm hiểu cách nào một chương trình chế biến (process) một tài liệu XML


Dĩ nhiên để chế biến một XML chương trình ứng dụng phải có cách đi lại bên trong tài liệu để lấy ra values của các Elements hay Attributes. Do đó người ta thiết kế ra ngôn ngữ XML Path language, mà ta gọi tắt là XPath. XPath đóng một vai trò quan trọng trong công tác trao đổi dữ liệu giữa các computers hay giữa các chương trình ứng dụng vì nó cho phép ta lựa chọn hay sàng lọc ra những tin tức nào mình muốn để trao đổi hay hiển thị.

Nếu khi làm việc với cơ sở dữ liệu ta dùng SQL statement Select .. from TableXYZ  WHERE ... để trích ra một số records từ một table, thì khi làm việc với XML, một table dữ liệu nho nhỏ, XPath cho ta những expressions về criteria (điều kiện) giống giống như clause WHERE trong SQL.


XPath là một chuẩn để process XML, cũng giống như SQL là một chuẩn để làm việc với cơ sở dữ liệu. Tiên phuông trong việc triển khai các chương trình áp dụng XPath là công tác của các công ty phần mềm lớn như Microsoft, Oracle, Sun, IBM, v.v. Sở dĩ ta cần có một chuẩn XPath là vì nó được áp dụng trong nhiều hoàn cảnh, nên cần phải có một lý thuyết rõ ràng, chính xác.

Lý thuyết về XPath hơi khô khan nhưng nó được áp dụng trong mọi kỹ thuật của gia đình XML. Cho nên bạn hãy kiên nhẫn nắm vững những điều căn bản về nó để khi nào gặp chỗ người ta dùng XPath thì mình nhận diện và hiểu được. So với võ thuật, thì XPath trong XML giống như Tấn pháp và cách thở. Tập luyện Tấn pháp thì mõi chân, tập thở thì nhàm chán, nhưng không có hai thứ đó thì ra chiêu không có công lực, chưa đánh đã thua rồi.


Ta sẽ chỉ học những thứ thường dùng trong XPath thôi, nếu bạn muốn có đầy đủ chi tiết về XPath thì có thể tham khão Specification của nó ở http://www.w3c.org/TR/xpath.

 

XML như một cây đối với XPath

XPath cho ta cú pháp để diễn tả cách đi lại trong XML. Ta coi một tài liệu XML như được đại diện bằng một tree (cây) có nhiều nodes. Mỗi Element hay Attribute là một node. Để minh họa ý niệm nầy, bạn hãy quan sát tài liệu đặt hàng (order) XML sau:

<?xml version="1.0"?>
<Order OrderNo="1047">

<OrderDate>2002-03-26</OrderDate>
<Customer>John Costello</Customer>
<Item>
<Product ProductID="1" UnitPrice="70">Chair</Product>

<Quantity>6</Quantity>
</Item>
<Item>
<Product ProductID="2" UnitPrice="250">Desk</Product>

<Quantity>1</Quantity>
</Item>
</Order>

 

Ta có thể biểu diễn XML trên bằng một Tree như dưới đây, trong đó node Element màu nâu, node Attribute màu xanh:

Chỉ định Location Path

Bạn có thể dùng XPath expression để chỉ định Location Path (lối đi đến vị trí) đến node nào hay trích ra (trả về) một hay nhiều nodes thỏa đúng điều kiện yêu cầu. XPath expression có thể là tuyệt đối, tức là lấy node gốc làm chuẩn hay tương đối, tức là khởi đầu từ node vừa mới được chọn. Node ấy được gọi là context node (node vai chính trong tình huống).

Có hai cách viết để diễn tả XPath Location, viết nguyên và viết tắt. Trong cả hai cách ta đều dùng dấu slash (/) để nói đến Document Element, tức là node gốc. Ta có thể đi lại trong các node của Tree giống giống như các node của Windows System Directory mà ta thấy trong Panel bên trái của Window Explorer. Ta cũng sẽ dùng những ký hiệu như slash /, một chấm . và hai chấm .. của Windows System File Folder cho cách viết tắt trong XPath Location để đi xuống các nodes con, cháu, chỉ định context node, hay đi ngược lên các nodes tổ tiên.

 

Location Path tuyệt đối

Chúng ta hãy tìm vài location paths trong cái Tree của tài liệu XML về đặt hàng nói trên. Muốn chọn cái node của Element Order (nó cũng là Root Element) bằng cú pháp nguyên, ta sẽ dùng XPath expression sau đây:

 
  /child::Order 

Dịch ra cú pháp tắt, expression nầy trở nên:

 
  /Order 

Đi ra nhánh của Tree, ta sẽ tìm được node Customer bằng cách dùng XPath expression sau:

 
  /child::Order/child::Customer 

Sau đây là XPath expression viết tắt tương đương:

 
  /Order/Customer 

Nếu bạn muốn lấy ra một node Attribute, bạn phải nói rõ điều nầy bằng cách dùng từ chìa khóa (keyword) attribute trong cách viết nguyên hay dùng character @ trong cú pháp tắt. Do đó để lấy Attribute OrderNo của Element Order, ta sẽ dùng XPath expression sau:

 
  /child::Order/attribute::OrderNo 

Cú pháp tắt cho Attribute OrderNo là:

 
  /Order/@OrderNo 

Để trích ra các nodes con cháu, tức là các nodes nhánh xa hơn, ta dùng keyword descendant trong cú pháp nguyên hay một double slash (//) trong cú pháp tắt. Thí dụ, để lấy ra các nodes Product trong tài liệu, bạn có thể dùng expression location path sau:

 
  /child::Order/descendant::Product 

Cú pháp tắt tương đương là:

 
  /Order//Product 

Bạn cũng có thể dùng wildcards (lá bài Joker) để nói đến những nodes mà tên của chúng không thành vấn đề. Thí dụ, dấu asterisk (*) wildcard chỉ định bất cứ node tên nào. Location path sau đây chọn tất cả các nodes con của Element Order:

 
  /child::Order/child::* 

Cú pháp tắt tương đương là:

 
  /Order/* 

 

Location Path tương đối

Nhiều khi XPath location paths là tương đối với context node, trong trường hợp ấy location path diễn tả cách lấy ra một node hay một số (set of) nodes tương đối với context node. Thí dụ như, nếu Element Item thứ nhất trong order là context node, thì location path tương đối để trích ra Element con Quantity là:

 
  child::Quantity 

Trong cú pháp tắt, location path tương đối là:

 
  Quantity 

Tương tự như vậy, để lấy ra Attribute ProductID của Element con Product, cái location path tương đối là:

 
  child::Product/attribute::ProductID 

Expression ấy dịch ra cú pháp tắt là:

 
  Product/@ProductID 

Để đi ngược lên phía trên của Tree, ta dùng keyword parent (cha). Dạng tắt tương đương của keyword nầy là hai dấu chấm (..). Thí dụ nếu context node là Element OrderDate, thì Attribute OrderNo có thể được lấy ra từ Element Order bằng cách dùng location path tương đối sau:

 
  parent::Order/attribute::OrderNo 

Để ý là cú pháp nầy chỉ trả về một trị số khi node cha tên Order. Nếu muốn lấy ra Attribute OrderNo từ node cha không cần biết nó tên gì bạn phải dùng expression sau:

 
  parent::*/attribute::OrderNo 

Viết theo kiểu tắt đơn giản hơn vì bạn không cần phải cung cấp tên của node cha. Bạn có thể nói đến node cha bằng cách dùng hai dấu chấm (..) như sau:

 
  ../@OrderNo 

Ngoài ra, bạn có thể nói đến chính context node bằng cách dùng hoặc keyword self hoặc một dấu chấm (.). Điều nầy rất tiện trong vài trường hợp, nhất là khi bạn muốn biết current context node là node nào.

Dùng điều kiện trong Location Path

Bạn có thể giới hạn số nodes lấy về bằng cách gắn thêm điều kiện sàng lọc vào location path. Cái điều kiện giới hạn một hay nhiều nodes được tháp vào expression bên trong một cặp ngoặc vuông ([]). Thí dụ, để lấy ra mọi Element Product có Attribute UnitPrice lớn hơn 70, bạn có thể dùng XPath expression sau đây:

 
  /child::Order/child::Item/child::Product[attribute::UnitPrice>70] 

Trong cú pháp tắt, nó là:

 
  /Order/Item/Product[@UnitPrice>70] 

Trong expression của điều kiện bạn cũng có thể dùng Xpath tương đối , do đó trong expression điều kiện bạn có thể dùng bất cứ node nào trong thứ bậc. Thí dụ sau đây lấy về những nodes Item có Element con Product với Attibute ProductID trị số bằng 1:

 
  /child::Order/child::Item[child::Product/attribute::ProductID=1] 

Dịch ra cú pháp tắt, ta có:

 
  /Order/Item[Product/@ProductID=1] 

Saturday, October 31, 2009

Vài nét về Access 2000

Từ đầu 1999, Microsoft giới thiệu bản beta 3 của Office 2000, trong đó chiếm vị trí xứng đáng là Access 2000 hay còn gọi là Access 9. Những tin tức đầu tiên về công cụ phát triển ứng dụng khách/chủ này chủ yếu tập trung vào 2 công nghệ mới với tên khá giống nhau là Microsoft Access Data Projects (ADPs) và Data Access Pages (DAPs). Cơ sở dữ liệu client/server dựng bằng Access bây giờ có thể được lưu trong tập tin với dạng thức kiểu mới gọi là .ADP (người dùng muốn dùng dạng thức .MDB cũng vẫn được). Tập tin ADP chứa các mẫu biểu (form), báo biểu (report) và các thành phần khác của giao diện, trong khi bảng và query (còn gọi là câu hỏi hoặc bảng truy vấn) được đưa vào tập tin dữ liệu của SQL Server 7. Nếu như trước kia, Access dùng Jet engine để truy xuất dữ liệu, thì nay có thể thay cơ cấu này bằng SQL Server 7, một cơ cấu CSDL mới, rất mạnh của Microsoft. Tất nhiên, vẫn có thể dùng Jet engine, nhưng cơ cấu này cũng được nâng cấp (phiên bản mới có số hiệu 4.x): ngôn ngữ SQL theo chuẩn ANSI 92, thêm khái niệm VIEW (khung nhìn), Procedure (thủ tục lưu sẵn), khái niệm giao tác phía Server, rồi một loạt kiểu dữ liệu mới như của SQL Server như Decimal,... Access 2000 hỗ trợ bộ ký tự Unicode mà không cần đến các phần mềm bổ trợ (add-on). Công cụ Access Upsizing Wizard nổi tiếng nay đã trở thành bộ phận cấu thành Access 2000 mà không cần phải tải xuống (download) từ cơ sở Web của Microsoft (đây là công cụ dùng để nâng cấp CSDL Jet hiện có lên SQL Server). Tập tin .MDB của Access 2000 không đọc được trong các phiên bản cũ của Access. Bạn có thể chuyển đổi tập tin .MDB thành .ADP một cách dễ dàng, tuy nhiên ngược lại thì không được. Tập tin .ADP cho phép vận hành Access như một ứng dụng mặt trước (front-end) trong khi SQL Server 7.0 dùng làm back-end (mặt sau, hậu trường). Không cần phải nạp cơ cấu Jet khi thực hiện ADP.

Còn DAP (Data Access Pages) thì sao? Nó cho phép dùng Access để tạo các ứng dụng Web động trên nền ASP (Active Server Pages). Truy xuất dữ liệu bây giờ chủ yếu thực hiện qua giao diện mới là ADO (Active Data Object). Có thể coi đây là mô hình đối tượng được sử dụng để làm việc với dữ liệu qua công nghệ OLE DB của Microsoft.

Bài báo này đề cập đến những tính năng mới được coi là thú vị nhất của Access 2000.

Đặc tính Dirty

Chắc bạn đã làm quen với đặc tính Dirty của mẫu biểu Access (chỉ có từ Access 97). Nó cho phép từ chương trình viết bằng VBA (Visual Basic for Applications) có thể xác định được dữ liệu trong bản ghi hiện thời (gắn với mẫu biểu) có thay đổi và đã được ghi chưa. Bạn có thể sửa đặc tính này thành giá trị False từ mã VBA để ghi bản ghi đó ra đĩa. Thế nhưng nếu ta cần thực hiện thao tác gì đó khi mẫu biểu bị thay đổi thì làm thế nào? Access 97 không có sự kiện gọi là Dirty. Chắc bạn đã đoán ra: Access 2000 cuối cùng đã có sự kiện (event) như vậy. Thủ tục xử lý sự kiện Dirty có tham biến Cancel. Khi cần có thể thực hiện lệnh Cancel = True để thôi (undo) không làm những gì vừa thay đổi với bản ghi hiện thời nữa. Nhược điểm lớn của sự kiện Dirty là nó chỉ xảy ra khi người nhập liệu bắt đầu sửa nội dung mẫu biểu, chứ không xảy ra khi đặc tính Dirty bị sửa thành False từ chương trình. Nên có thêm sự kiện, chẳng hạn với tên là Undo để xử lý tình huống đó (bạn có thể lấy trình FrmSmp 97.exe từ cơ sở Web của Microsoft để tham khảo cách mô phỏng sự kiện After undo, nó sử dụng một điều khiển tính toán với biểu thức là một hàm người dùng, và hàm này thực hiện mỗi khi đặc tính Dirty của Access 97 thay đổi. Dùng kỹ thuật này để mô phỏng sự kiện Dirty, nhưng không hiệu quả bằng sự kiện Dirty cài sẵn trong Access 2000).

Định dạng có điều kiện

Đây là một trong những tính năng mà người lập trình Access khao khát nhất: làm thế nào để chỉ một số dòng nào đó (ví dụ: các dòng với doanh số lớn hơn 10.000 USD) của mẫu hoặc báo biểu hiện lên với dạng thức theo ý muốn (ví dụ: có màu đậm hơn các dòng khác, để dễ đọc, dễ nhấn mạnh). Với report thì có thủ thuật thêm cấu trúc IF - Endif vào thủ tục xử lý sự kiện Format của vùng (section) chứa hộp văn bản cần kiểm tra và nhấn mạnh. (Nếu thỏa điều kiện nào đó thì sửa các đặc tính Font, Fontweight,... của điều khiển cần định dạng riêng.) Tương tự, đối với mẫu biểu kiểu Single (đơn bản ghi) đưa nhóm lệnh kể trên vào thủ tục xử lý Current. Thế nhưng với kiểu mẫu biểu liên kế (Continuous Form, mẫu biểu đa bản ghi), làm như vậy sẽ thay đổi dạng thức cho tất cả các bản ghi! Nghĩa là không đạt được mục đích đặt ra. Vâng, bây giờ thì nhóm Access của Microsoft đã lắng nghe nguyện vọng của người sử dụng: có cách dễ dàng định dạng có điều kiện (conditional formatting) cho từng hộp văn bản, từng hộp chọn combo, từng dòng một. Có thể xác lập nhiều điều kiện định dạng cho mỗi điều khiển (dưới dạng biểu thức luận lý hay trạng thái điều khiển đang trong focus hay không). Nếu có vài điều kiện đúng, sẽ chọn điều kiện đúng đầu tiên kể từ đầu danh sách. Bạn đặt điều kiện trong cả chế độ Design (khi thiết kế) hoặc chế độ Form (khi mở mẫu biểu để làm việc, tức là định dạng động, trong thời gian vào hoặc xem số liệu). Hình 1 cho thấy hộp thoại Conditional Formatting mở ra khi người dùng nhập liệu hoặc xem form bằng cách vào thực đơn Format, sau đó chọn Conditional Formatting.

Hình 1. Hộp thoại định dạng có điều kiện mở trong Form View.

Người lập trình VBA có thể kiểm soát việc định dạng có điều kiện bằng cách thêm hoặc loại bỏ các đối tượng kiểu FormatCondition từ sưu tập (collection) FormatConditions, và đặt lại các đặc tính của các đối tượng đó. Ví dụ, để doanh số hàng tháng trở nên đậm và có màu xanh dương nếu lớn hơn hạn mức nào đó (nhập sẵn vào hộp văn bản textMonthQuota của mẫu biểu), ta dùng đoạn mã sau:

With Forms!frmSales!txtMonthSales. FormatConditions
.Add(acFieldValue, acGreaterthan, "=[txtMonthQuota]")
.FontBold = True
.ForeColor = vbBlue
End With

Gắn mẫu biểu với bộ bản ghi

Ngay trong Access 2.0, người lập trình đã có nhiều cách để kiểm soát đặc tính Record Source của mẫu biểu. Bạn có thể gửi tên bảng, tên câu hỏi (query) hoặc cả một lệnh SELECT của SQL vào đặc tính này để đặc tả nguồn bản ghi. Với bộ bản ghi (recordset) tính được trong VBA thì rắc rối hơn: phải tạo bảng trung gian hoặc bảng truy vấn chứa dữ liệu cần thiết. Trong Access 2000 có thể gắn recordset tính được với mẫu biểu. Access 97 truy cập bộ bản ghi của mẫu biểu bằng đặc tính RecordsetClone, nhưng vẫn chưa có đặc tính Recordset để ấn định bộ bản ghi nguồn.

Tính năng mới này của Access 2000 rất linh hoạt, nhất là khi tạo recordset trong một giao tác (transaction). Khi quay lui (roll back) toàn giao tác, tất cả các thay đổi làm với mẫu biểu dựa trên bộ dữ liệu tạo trong giao tác, kể cả các thay đổi tác động đến nhiều bản ghi, sẽ được hủy. Trong quá khứ thì cực kỳ vất vả: thông thường phải dùng bảng trung gian hoặc mảng dữ liệu.

Hình 2: Đăng ký chế độ Compact on Close và tập tin Access sẽ được nén tự động khi đóng (miễn là không có ai khác vẫn còn mở nó).

Có thể gắn một recordset với vài mẫu biểu một lúc. Dữ liệu trong mẫu biểu này sẽ tự động đồng bộ với dữ liệu trong form khác, mà quay lui giao tác cũng sẽ quay lui đối với dữ liệu trong tất cả các biểu mẫu. Ngay cả khi dùng các recordset với nhiều mẫu biểu mà các recordset đó được tạo trong một giao tác, chúng cũng rollback được cùng nhau.

Trong các tập tin ADP, các bộ bản ghi ADO có thể cập nhập (sửa) được qua form nếu các ADP này được tối ưu để dùng OLE DB tương tác với SQL server. Nếu dùng Jet (tức dùng tập tin .MDB) vẫn phải sử dụng DAO (Data Access Object) để tạo recordset kiểu read/write cho mẫu biểu, còn dùng bộ bản ghi ADO cho mẫu biểu của .MDB thì nó chỉ có tính read-only mà thôi. Có lẽ Microsoft phải khắc phục nhược điểm này của ADO trong MDB khi đưa ra phiên bản cuối cùng của Access 2000.

Tự động nén tập tin

Đây là tính năng rất hữu ích, và để Access làm được điều đó khi đóng tập tin, chỉ việc vào trang General của hộp thoại Options, sau đó đánh dấu chọn ô Compact on Close (xem hình 2).

Thông thường ứng dụng Access được đưa vào MDB mặt trước (chứa query, form, report, module), dữ liệu tách ra tập tin MDB riêng (mặt sau). Đóng tự động được thực hiện cho MDB mặt trước, và cần một thủ thuật nhỏ để đảm bảo nén cả tập tin dữ liệu ở mặt sau. Access đòi hỏi tập tin này phải được mở trong chế độ Exclusive (độc chiếm) thì mới thực hiện compact được, tuy nhiên, ít nhất là từ nay không cần phải lo nén tập tin mặt trước nữa.

Tại sao lại phải thường xuyên nén dữ liệu, trong khi bạn không tạo bảng tạm thời nào cả? Trên thực tế, Access tạo rất nhiều đối tượng trung gian và làm cho CSDL liên tục phình ra, do đó bị phân đoạn và giảm hiệu năng truy xuất.

Hình 3. Từ nay Access 2000 dùng chung VBE với các thành phần khác của Office 2000.

Cần lưu ý rằng, nén tập tin có tác dụng đánh dấu các query cần được biên dịch lại trong lần vận hành kế tiếp. Khi bảng truy vấn lần đầu thực hiện sau khi thiết kế, cơ cấu Jet thiết lập một lược đồ truy vấn dựa trên các số liệu thống kê thu thập được. Nếu có ít số liệu (thường ban đầu dùng số liệu thử do người lập trình tự tạo), lược đồ truy vấn không sử dụng các chỉ mục mà trực tiếp quét các bản ghi trong bảng từ đầu đến cuối vì như thế sẽ nhanh hơn. Khi hệ thống áp dụng cho số liệu thực, liên tục biến đổi tăng dần, lược đồ truy vấn cũ không còn thích hợp nữa. Chính việc nén tập tin có tác dụng thiết lập lược đồ truy vấn mới cho query, dựa trên tình trạng mới nhất của số liệu. Nén cũng kéo theo việc sửa chữa tập tin, do đó không cần thực hiện thao tác repair như trong Access 2.0. Nén tự động sẽ không thực hiện nếu không tiết kiệm thêm ít nhất 256 KB.

Bộ soạn thảo VBE

Làm việc với Word, Excel chắc bạn đã quen thuộc với Visual Basic Editor (VBE). Bản thân Access 95 đã chấp nhận VBA nhưng đến Access 97 vẫn trung thành với giao diện soạn thảo chương trình theo kiểu riêng. Kể từ Office 2000, tất cả các ứng dụng cấu thành của nó, trong đó có Access, đều chung VBE với giao diện thống nhất (Hình 3).

Dường như đây là một bước thụt lùi của Access 2000. Trong phần lớn các phần mềm dùng VBA, các mẫu biểu được thiết kế ngay trong VBE. Người lập trình Access 2000 buộc phải tiến/lui giữa cửa sổ VBE và cửa sổ Access nơi có các mẫu biểu đang mở.

Nếu là người lập trình từng trải, bạn có thể đóng cửa sổ Properties trong VBE vì nó chỉ lặp lại những gì có trong các hộp thoại Access, không có cả các đặc tính của điều khiển. Cửa sổ Project Explorer theo phong cách treeview (dạng cây) thật hữu ích khi làm việc với các CSDL thư viện. Ngoài ra, Project Explorer còn có khả năng mở rộng, cho thấy cả những gì không có trong cửa sổ CSDL của Access. Bạn có thể làm cho cửa sổ Immediate di động tự do giống như cửa sổ Debug trước kia. Nếu không thấy cánh Locals hoặc Watch, có thể mở chúng trong cửa sổ riêng nằm trên phần còn lại là cửa sổ soạn thảo mã VBA, không khác gì mấy so với trong Access 97, ngoại trừ việc các đơn thể chỉ mở trong khuôn khổ của cửa sổ VBE mà thôi. Bản thân VBE có gì mới? Hấp dẫn nhất là thanh công cụ Edit: có cặp nút lệnh cho phép thêm/bớt câu chú thích cho toàn khối mã chỉ bằng một thao tác nhấp chuột. Điểm mới nữa là thanh Edit cho phép đặt thẻ đánh dấu (bookmark) vào văn bản mã trình. Khi cần thiết có thể dễ dàng quay lại những nơi đã đặt dấu, hoàn toàn chỉ bằng cách nhấp vào lệnh tương ứng trong thanh công cụ. Thực ra thì bookmark đã có từ thời Access 97 nhưng thao tác đặt lại nằm sâu trong hệ thống thực đơn, do đó nhiều người không để ý và chẳng bao giờ dùng đến.

Hình 4. CurrentProject cho phép nhận được nhiều thông tin mới, rất hữu ích.

VBE còn hỗ trợ mô hình các công cụ bổ trợ linh hoạt, cho phép tùy biến môi trường mã hóa của người lập trình. Bạn tự động thêm khối chú thích hoặc đoạn mã xử lý sự kiện trong thủ tục hoặc hàm mới? Có thể tự tạo add-in để làm điều đó hoặc dùng các công cụ do người khác cung cấp. Dự đoán sẽ có nhiều phương tiện bổ trợ cho VBE xuất hiện trên thị trường.

AutoCorrect

Giả sử bạn dùng trường tên là CustomerID trong một hoặc nhiều bảng. Một ngày nào đó bạn muốn đổi tên nó thành ClientID. Như trước kia thì thật vất vả: phải rà soát tất cả bảng truy vấn (query) để tìm các trường CustomerID đang sử dụng và đổi nó thành tên mới. Cũng làm như vậy với các form và report để thay lại các nguồn điều khiển gắn với trường cũ. Tin tốt lành cho chúng ta: Access 2000 tự động đổi tên trường trong tất cả các thành phần liên quan kể trên, nhưng đừng vội hân hoan: hệ chưa mò được tới các module, các đoạn mã lập trình và recordset. Bạn vẫn phải sửa bằng tay như thường làm, do đó đừng vội vứt bỏ SpeedFerret, một sản phẩm thứ ba, vì chắc nó vẫn còn hữu hiệu cho Access 2000. Tuy nhiên, dùng AutoCorrect của Access 2000 một cách thận trọng cũng giúp được nhiều việc.

Hình 5: Jet 4.0 bây giờ hỗ trợ khóa chốt đến từng bản ghi.

CurrentProject

Có một đối tượng mới trong Access 2000 gọi là CurrentProject.

Những ai từng lập trình DAO chắc khá quen thuộc với hàm CurrentDb () để tham chiếu tới CSDL đang mở. CurrentProject cũng có mục đích tương tự nhưng áp dụng cho cả ADO, ví dụ CurrentProject.Connection trả lại đối tượng kết nối ADO. Ngoài ra còn có CodeProject gần giống với hàm CodeDb () trong DAO để dùng với các add-in. Ta thực hiện một số lệnh sau để kiểm tra trong cửa sổ Immediate:

?CurrentProject.FullName
D:\Temp\db1.mdb
?CurrentProject.Name
db1.mdb
?CurrentProject.Path
D:\Temp

Đối tượng CurrentProject có các sưu tập (collection) chứa tất cả các đối tượng khác của Access, chẳng hạn AllForms, AllReports, AllMacros, AllModules và AllDataAccessPages. Mỗi sưu tập này chứa các đối tượng kiểu AccessObject với nhiều đặc tính (Property) rất hữu ích:

?CurrentProject.AllForms.Count
6
?CurrentProject.AllForms (5) .Name
frmQuery1
?CurrentProject.AllForms (5) .IsLoaded
False

Còn với các bảng và query thì sao? Có đối tượng khác gọi là CurrentData với đặc tính là các sưu tập AllTables, AllQueries, rồi cả AllViews, AllStoredProcedures và AllDatabaseDiagrams.

Tuy CurrentProject.Connection trả về đối tượng kết nối ADO, đặc tính ngầm định của đối tượng kết nối này là một chuỗi kết nối (Connect String):

?CurrentProject.Connection

Kết quả là một chuỗi ký tự bao gồm các tham trị chia tách nhau bằng dấu chấm phẩy (;). Dùng các hàm mới của Access 2000, trong đó có Split() và Filter() để tách và lấy ra các tham trị cần thiết.

Các hàm chuẩn mới

Một loạt hàm mới được bổ sung so với Access 97, dùng để xử lý xâu ký tự: Replace(), InstrRev(), StrReverse(), Split(), Join() và Filter().

Hàm Replace() dùng để thay xâu con của xâu nào đó bằng xâu con mới:

?Replace ("a1a2a3a4a5", "a", "b")
b1b2b3b4b5
?Replace ("a1a2a3a4a5", "a", "b", 3)
b2b3b4b5
?Replace ("a1a2a3a4a5", "a", "b", 3, 2)
b2b3a4a5

Trong 2 ví dụ cuối, số 3 ở tham số thứ tư dùng chỉ vị trí từ đó bắt đầu cần thay thế (và kết quả cũng từ đó luôn). Tham số thứ 5 trong ví dụ cuối cùng để đặc tả số lần phải thay (xâu con có thể hiện diện nhiều lần).

Hàm StrReverse() trả về chuỗi ký tự đảo ngược (không rõ thực tế ứng dụng CSDL có cần đến hàm này không?).

?StrReverse ("abcdef")
fedcba

Hàm InstrRev() có cơ chế làm việc như Instr() nhưng tìm kiếm ngược từ ký tự cuối đến ký tự đầu (hàm này thì thật sự cần thiết):

?InstrRv ("C:\MyPath\MyFile.ext", "\")
10

Các hàm Split(), Join() và Filter() cũng rất hữu ích. Split() chuyển đổi xâu ký tự có chia tách (bởi một ký tự nào đó, ví dụ dấu chấm phẩy) thành mảng các giá trị. Join() thực hiện thao tác ngược lại, từ mảng trở về xâu ký tự có chia tách. Filter() trích từ mảng các dòng thỏa mãn điều kiện nào đó.

? Filter(Split(CurrentProject.Connection, ","), _
"Data Source = ") (0)
Data Source=D:\Temp\db1.mdb

Thêm một bước nữa thì nhận được trị của Data Source.

? Split (Filter(Split(CurrentProject .Connection, ";"), _
"Data Source = ") (0) ,"=") (1)
D:\Temp\db1.mdb

Nếu đã quen thuộc với ngôn ngữ Lisp, chắc bạn rất hài lòng với bộ hàm trên và tự hỏi: tại sao đến bây giờ VBA mới có được khả năng phân tích xâu ký tự như vậy?

Ngang ngửa với VB 6

Những năm qua, người lập trình Access dùng VBA luôn lạc hậu so với Visual Basic, do đó có ý nghĩ cho rằng VBA là một tập con của VB. Sự thực thì VBA và VB luôn là một, có điều là người lập trình Visual Basic có được phiên bản mới hơn một chút. Giờ đây Microsoft đảm bảo Visual Basic và VBA đồng bộ với nhau. Như vậy, Office 2000 có ngôn ngữ lập trình hoàn toàn ngang ngửa với VB 6.0. Dưới đây tóm lược một số tính năng nâng cao của VBA mới.

- Bộ chuyển AddressOf cho phép truyền địa chỉ hàm gọi ngược cho thủ tục khác.

- Lệnh Implements được dùng với các đơn thể lớp để đặc tả lớp (class) thực thi giao diện (tập hợp các đặc tính và phương thức) định nghĩa trong một lớp khác. Như vậy, VBA bây giờ có tính năng đa hình (polymorphism), nghĩa là giao diện chuẩn có hành vi khác trong các lớp khác nhau.

- Với Access 97, bạn có thể dùng khai báo With Events trong đơn thể lớp để tạo khoang sự kiện, do đó đơn thể lớp đó có thể bắt được sự kiện phát sinh trong đối tượng. Từ nay có thể dùng lệnh Event để khai báo sự kiện theo ý muốn và lệnh RaiseEvent để làm cho nó xảy ra bất cứ lúc nào.

- Từ khóa Enum cho phép khai báo các hằng liệt kê, chẳng hạn như các hằng bắt đầu bằng ac, vb hoặc db. Các biến và tham số sau đó có thể được đăng ký với kiểu mới.

- Từ khóa Friend thêm lựa chọn thứ ba vào danh sách các khai báo (trước đó có Public và Private) khi cần định nghĩa phạm vi của thủ tục trong đơn thể lớp. Các thủ tục có tính Friend thấy được từ tất cả các thủ tục khác trong dự án. Khác với Public, chúng không thấy được bên ngoài dự án. Nếu dùng VBA để dựng các Com server cho các trình khác sử dụng, phạm vi kiểu Friend rất hữu ích.

- Đối tượng Debug có thêm phương thức Assert dùng đặt điểm ngắt vào mã trình. Ngắt sẽ xảy ra khi tại điểm đó biểu thức đặc tả trong Assert cho trị False. Lại thêm một cách mới để gỡ rối chương trình khi khó tìm được lỗi.

Jet Engine 4.0

Gần đây có nhiều tin đồn về giờ tận thế của Jet, một cơ cấu CSDL vốn dùng từ lâu nay cho Access (ở ta hay lẫn Jet với Access và một vài cổ động viên còn sót lại của FoxPro for DOS đã vội hoan hỉ là Access sắp chết - ND). Trên thực tế, người dùng được lựa chọn trong 2 khả năng: dùng Jet Engine 4.0 hoặc SQL Server 7.0 làm động cơ cho Access. Phiên bản 4.0 của Jet mạnh mẽ hơn bao giờ hết. Nhiều ứng dụng Access có thể không cần đến cơ cấu SQL Server 7 quá mạnh, và nhóm Jet của Microsoft vẫn nỗ lực hoàn thiện sản phẩm truyền thống của mình.

Động cơ Jet mới cho phép khóa chốt đến từng bản ghi (xem tùy chọn tương ứng trong trang Advanced thuộc hộp thoại Options ở hình 5).

Người dùng các phần mềm CSDL khác thường chê Access (đúng hơn: cơ cấu Jet của nó) là chỉ khoá chốt được toàn trang (page-level locking) khi bản ghi nào trong đó cần khóa. Từ Jet 3.x trở về trước một trang CSDL có dung lượng 2 KB. Jet 4.0 dùng trang 4 KB do đó nếu không hỗ trợ khóa chốt đến từng bản ghi thay cho việc khóa chốt toàn trang (gấp đôi so với trước), nhiều bản ghi sẽ bị "khóa lây". Dung lượng trang 4 KB là để hỗ trợ bộ mã Unicode, vì theo bộ này mỗi ký tự sẽ chiếm 2 byte. Giờ đây kích cỡ tối đa của tập tin MDB được nâng lên 2 GB so với 1 GB trước đây.

Việc khóa chốt theo kiểu nào cũng được Jet xác định một cách thông minh. Nếu có nhiều bản ghi trong trang 4 KB nào đó được khóa chốt, Jet tự động khóa cả trang cho hiệu quả, thậm chí nó khóa chốt cả bảng luôn nếu không có người dùng nào khác trên mạng truy cập bảng đó (đúng hơn: đang sửa - ND)

Nhiều đặc tính mới khác của Jet chủ yếu định hướng cho mô hình đối tượng ADO mà Microsoft khuyến nghị sử dụng thay cho mô hình DAO. Mô hình DAO cũ sẽ vẫn còn và giữ được giá trị sử dụng, nhất là về phương diện bảo mật và nhân bản (replication).

Dùng ADO nghĩa là sử dụng ngôn ngữ SQL đổi mới. Dưới đây liệt kê một số điểm mới của SQL theo chuẩn ANSI-92 mà Jet 4.0 hỗ trợ.

- Thêm các lệnh GRANT, REVOKE cho mục đích bảo mật

- Thêm các lệnh CREATE và DROP để tạo và loại bỏ câu hỏi (VIEW và PROCEDURE)

- CASCADE dùng để định nghĩa tính toàn vẹn tham chiếu

- Ràng buộc CHECK dùng để đặc tả biểu thức luận lý mà các bản ghi trong một hoặc nhiều bản phải thỏa.

- Các lệnh ALTER TABLE và ALTER COLUMN để sửa cấu trúc bảng mà không phải thêm cột mới, sao chép cột cũ sang và loại bỏ cột cũ như trước kia.

- IDENTITY là từ khóa đặc tả tính tăng tự động của cột

- Thêm một số kiểu cột mới để tương hợp với SQL Server, ví dụ kiểu Decimal

Có nên nâng cấp?

Khi bài báo này đến tay bạn đọc, vẫn còn quá sớm để phán xét về phiên bản mới của Access. Một số tính năng đề cập ở trên có thể không có trong bản chính thức của Access 2000 hoặc khác đi một chút. Việc tích hợp VBE với Access còn gây nhiều bàn cãi nhưng những bước tiếp theo có thể làm cho tính năng này sáng giá hơn. Microsoft rõ ràng là đã chuyển hẳn sang hướng xây dựng phần mềm tận dụng tối đa các thành phần dùng chung, tất nhiên có lúc phải trả giá về hiệu năng.

Ai đã từng trải qua thời kỳ lập trình trong Access 2.0 mới càng thấu hiểu giá trị của các thành phần nhiều mega đó, tuy chúng còn ở mức sơ khai và hy vọng hoàn chỉnh hơn theo đà hoàn thiện mô hình đối tượng chung của Microsoft. Sản phẩm mới chịu búa rìu dư luận là chuyện thường tình, và Access 2000 không là ngoại lệ.

Thursday, October 29, 2009

Quản Lý Bảo Mật Database Trong Orcale 8.05

Chương này mô tả cách sử dụng Security Manager để điều khiển bảo mật database. Với Security Manager, bạn có thể quản lý users, roles, và profiles.

Cách khởi động Security Manager

Để khởi động Security Manager, click biểu tượng Security trong Launch Palette hoặc chọn Security Manager từ menu Console Tools.

·Nếu kết nối đến database đã được làm thông qua Console hoặc ứng dụng, cửa sổ Security hiển thị.

Nếu kết nối database hợp lệ mà chưa được làm, hộp thoại Login information hiểu thị.

Note:

Bạn có thể thay đổi kết nối database bằng tùy chọn Change Database Connection trong menu File.

Sau khi Security Manager được kết nối thành công đến database, thư mục Users, Roles, và Profiles hiển thị trong danh sách cây ở phía bên trái của cửa số Security. Những thư mục này được định vị trong thư mục database, thư mục mà hiển thị tên của database là ứng dụng được kết nối đến.

Hình III.1 Security Manager

Sự hiện thị ở phía bên phải cửa sổ được xác định bởi đối tượng được chọn ở phía bên trái của màn hình. Phía bên phải có thể chứa danh sách multi-column, thẻ thuộc tính, hoặc những thông tin khác. Ví dụ cửa sổ Security Manager trình bày trong Hình III.1, "Security Manager".

Những menu Security Manager

Security Manager bao gồm những menu chuẩn: File, View, Log, và Help, cùng với những menu User, Profile, và Role. Những tùy chọn đối với mọi menu này được mô tả trong chương này.

Những menu di động cũng có thể hoạt động khi bạn right-click để chọn đối tượng cụ thể từ danh sách cây hoặc danh sách multi-column. Tính năng này cung cấp cách nhanh để truy xuất tập con về những tùy chọn menu được cung cấp trong thanh menu.

Menu User

Menu User chứa những tùy chọn menu sau:

Create

Tạo user mới.

Create Like

Tạo user mới dựa và user được chọn trong danh sách cây.

Remove

Xóa user được chọn từ danh sách cây.

Revoke Privilege

Gỡ bỏ đặc quyền hoặc role được chọn.

Show Dependencies

Hiển thị những đối tượng database dựa vào user được chọn và bất kỳ những đố tượng mà user được chọn có liên quan.

Add Privileges to User

Thêm nhiều đặc quyền cho một hoặc nhiều user.

Change Account Status (Oracle 8)

Unlock: Mở khoá tài khoản của user và cho phép truy xuất đến tài khoản.

Lock: Khoá tài khoản của user và không cho phép truy xuất đến tài khoản.

Expire: Hết hiệu lực password user.

Menu Role

Menu Role chứa những tùy chọn menu sau:

Create

Tạo role mới.

Create Like

Tạo role mới dựa vào role được chọn.

Remove

Xoá role được chọn.

Revoke Privilege

Gỡ bở đặc quyền hoặc role từ role.

Show Dependencies

Hiển thị những đối tượng database dựa và role được chọn và bất kỳ những đối tượng mà role được chọn tham khảo đến.

Add Privileges to Roles

Thêm những đặc quyền hoặc role cho roles.

Note: Những tùy chọn menu này có hiệu lực tùy thuộc vào đối tượng được chọn.

Menu Profile

Menu Profile chứa những tùy chọn menu sau:

Create

Tạo profile mới.

Create Like

Tạo profile mới mà dựa vào profile được chọn.

Remove

Xoá profile được chọn.

Show Dependencies

Hiển thị những đối tượng database dựa vào profile được chọn và bất kỳ những đối tượng mà profile được chọn có liên quan.

Assign Profile to Users

Chỉ định profile đến user cụ thể.

Note: Những tùy chọn menu này có hiệu lực tùy vào đối tượng được chọn trong danh sách cây.

Những Đối tượng và Thư mục Security Manager

Những đối tượng trong danh sách cây được nhận dạng theo những đối tượng khác nhau. Trong danh sách:

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Biểu tượng thư mục nhận dạng đối tượng kiểu thư mục.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Biểu tượng chỉ có một người mô tả user.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Biểu tượng mặt nạ biểu thị role hoặc role con.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Biểu tượng cuộn sách mô tả profile.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Biểu tượng cánh cửa mở nhận dạng đặc quyền hệ thống.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Cái va ly trình bày và nhận dạng object privilege.

Attention:

Biểu tượng Roles, Object Privileges, và System Privileges xuất hiện với chìa khoá che nếu những đối tượng được cấp sử dụng tùy chọn Admin/Grant.

Thư mục Users

Thư mục kiểu đối tượng User chứa thống tin về những user trong database được xắp xếp theo thứ tự alphabe trong cấu trúc cây. User riêng lẻ có thể được mở rộng để trình bày roles, system privileges, và object privileges được cấp cho user.

Khi bạn chọn:

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Thư mục Users group, danh sách multi-column hiển thị hàng tóm tắt thông tin về mọi user trong database.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> User riêng lẻ, những thiết lập chi tiết đối với user được hiển thị trong thẻ thuộc tính.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Thư mục Roles, System Privileges, hoặc Object Privileges được cấp ở bên dưới user riêng lẻ, danh sách multi-column về những đặc quyền hoặc roles được cấp cho user hiển thị. Xem Danh sách Multi-Column về những đặc quyền.

Danh sách Multi-Column Users
Cách tạo User
Tạo User giống nhau
Söûa ñoåi User
Gôõ boû User
Theâm nhöõng Ñaëc quyeàn hoaëc Role cho User
Gôõ boû nhöõng ñaëc quyeàn hoaëc Role töø User
Danh sách Multi-Column và những ñaëc quyeàn

Danh sách Multi-Column Users

Danh sách multi-column users hiển thị khi thư mục User được chọn trong danh sách cây. Danh sách chứa hàng thông tin tóm tắt về những user trong thư mục Users.

Nếu bạn chọn biểu tượng User riêng lẻ, và biểu tượng đó cũng có trên nhánh chính của thư mục Database, những cột của danh sách multi-column tóm tắt tất cả thông tin từ trang General trong thẻ thuộc tính Create User. Để biết thêm thông tin về những cột này, xem mô tả về thẻ thuộc tính trong Cách tạo User.

Suggestion: Nếu danh sách multi-column rộng hơn vùng hiển thị cửa sổ của nó, bạn có thể tăng vùng view bằng cách thay đổi kích thước cửa sổ ứng dụng hoặc kéo vạch ngăn cách giữa phần bên trái và bên phải của cửa sổ.

Cách tạo User

Để tạo user mới:

Chọn Create từ menu User. Thẻ thuộc tính Create User xuất hiện.

Điền vào thông tin trong thẻ thuộc tính thích hợp.

Click nút Create sau đón chỉ định những thống số cần thiết.

Thẻ thuộc tính Create User gồm có những trang sau khi trong chế độ Advanced:

General (Basic UI mode)

Roles/Privileges (Advanced UI mode)

Object Privileges (Advanced UI mode)

Quotas (Advanced UI mode)

Thẻ thuộc tính Create User: trang General

Trang General cho phép bạn chỉ định tên của user (khi tạo user mới), profile ngầm định của user, cách thức xác nhận, và tablespace ngầm định. Thẻ thuộc tính Create User chứa những mục sau:

Name

Tên của user cần được tạo. Nhập tên của user mới. Username có thể chỉ chứa những ký tự trong bộ ký tự database của bạn và có thể dài tối đa 30 byte.

Profile

Profile được gán cho user. Sử dụng danh sách drop-down chọn profile bạn muốn gán cho user. Profile DEFAULT được gán nếu bạn không thực hiện sự chọn lựa này.

Authentication

Phương pháp Oracle sử dụng để xác nhận user.

Global: Chỉ định rằng user được nhận dạng toàn bộ giữa những database. Tùy chọn xác nhận toàn cục chỉ có giá trị với Oracle 8 databases.

External: Chỉ định rằng hệ điều hành kiểu tra user.

Password: Chỉ định rằng password được yêu cầu để đăng nhập. Nhập password trong trường mục nhập văn bản ngay sau. Nhập password lại trong trường mục nhập văn bản Confirm để xác minh lại.

Expire Now: Bắt buộc password của user hết hiệu lực ngay lập tức. Nếu bạn tạo user mới với tùy chọn này được chọn, password của user phải được thay đổi trong trong lần thử đăng nhập lần đầu tiên. Tính năng này có giá trị chỉ cho Oracle8 databases.

Tablespaces

Những tablespace tạm thời và ngầm định của user.

Default: Sử dụng danh sách drop-down để chọn tablespace ngầm định cho những đối tượng user được tạo.

Temporary: Sử dụng danh sách drop-down để chọn những đoạn tạm thời cho user.

Status (Oracle 8 only)

Trang thái hoạt động của tài khoản của user.

Lock: Khoá tài khoản của user và ngăn cản sự truy xuất thêm nữa.

Unlock: Mở khoá tài khoản của user và cho phép truy xuất đến tài khoản.

Thẻ thuộc tính Create User: trang Roles/Privileges

Trên trang Privileges của thẻ thuộc tính Create User, bạn có thể chỉ định system privileges và roles được gán cho user. Trang Privileges chứa những mục sau:

Privilege Type

Danh sách drop-down chứa System Privileges và Roles. Sự lựa chọn của bạn trong danh sách drop-down xác định cái gì được hiển thị trên cái còn lại của trang.

Available

Danh sách những roles hoặc system privileges có giá trị để chỉ định đến user.

Roles: Nếu bạn đã chọn Roles như là kiểu đặc quyền, những role mà bạn đã cấp cho user hiển thị trong danh sách cuộn. Đây là những role bạn đã cấp và những role bạn đã cấp với tùy chọn Admin.

Những role mà bạn thêm cho user được gán như là những role ngầm định trừ khi bạn thay đổi sự chỉ định bằng cách click vào mục nhập của role trong cột Default.

Bạn phải thêm những role với Admin Option bằng thao tác riêng lẻ từ những role bạn muốn thêm mà không có Admin Option.

Note:

Khi bạn cấp role DBA và RESOURCE cho user hoặc role bằng Oracle7 release 7.2.2 hoặc cao hơn, user hoặc role cũng được cấp đặc quyền hệ thống UNLIMITED TABLESPACE. Khi bạn hủy bỏ role từ user hoặc role, đặc quyền hệ thống UNLIMITED TABLESPACE cũng được hủy bỏ. UNLIMITED TABLESPACE cũng có thể được hủy bỏ không phụ thuộc vào role DBA và RESOURCE.

System Privileges: Nếu bạn chọn System Privileges như là kiểu đặc quyền, những đặc quyền hệ thống mà bạn có thể cấp cho user thì hiển thị trong danh sách cuộn. Đây là những đặc quyền hệ thống bạn được cấp với Admin Option. Nếu bạn có đặc quyền hệ thống GRANT ANY PRIVILEGE, tất cả đặc quyền được liệt kê. Chọn những đặc quyền mà bạn muốn thêm đến user.

Attention:

Nếu bạn muốn cấp tùy chọn Admin hoặc Grant của privilege hoặc role hiện hành, bạn phải thêm privilege hoặc role bằng tùy chọn Admin hoặc Grant được chỉ định như bạn mong muốn.

Up and Down Arrows

Up Arrow thêm những role hoặc system privilege mà được chọn trong danh sách Available đến bảng tính (spreadsheet) Granted.

Down Arrow gỡ bỏ những role hoặc system privilege mà được chọn trong bảng tính Granted.

Granted

Bảng tính có thể soạn thảo hiển thị những role hoặc đặc quyền hệ thống được gán cho user. Những sự thêm mới (được chọn nhưng chưa được áp dụng) được nhận dạng bởi hand với ký hiệu dấu cộng. Khi tạo user, bảng tính gồm có ba cột:

System Privilege or Role: Tên của role hoặc đặc quyền hệ thống.

Admin Option: Khi được chọn, cho phép user cấp những đặc quyền hệ thống cho những user hoặc role khác. Ngầm định, Admin Option bị vô hiệu hóa. Bạn cho phép Admin Option bằng cách click vào mục nhập bảng tính. Trong trường hợp này, "X" là chọn.

Default: (Chỉ có trong thẻ thuộc tính Users): Khi được chọn, thiết lập role ngầm định cho user trong lúc đăng nhập hệ thống.

Khi tạo Role, bảng tính ngày gồm có hai cột: System Privilege hoặc Role và Admin Option.

Thẻ thuộc tính Create User: trang Object Privileges

Trang Object Privileges, có giá trị trong chế độ Advance UI, cho phép bạn cấp hoặc hủy bỏ những đặc quyền đối với user cụ thể trên những đối tượng schema. Trang này chứa những mục sau:

Objects

Cây liệt kê những schema trong database và những đối tượng trong schema hiển thị trong cửa số Object. Click vào '+' ở phía bên trái của biểu tượng thư mục để hiển thị những kiểu đối tượng được chứa trong schema, sau đó click vào '+' ở phía bên trái của kiểu đối tượng để hiển thị những đối tượng hiện thời.

Chọn đối tượng từ danh sách cây mà bạn muốn cấp những đặc quyền cho nó. Sau khi đối tượng được chọn, những đặc quyền có giá trị cho đối tượng được hiển thị ở phía bên phải trong danh sách cuộn Available Privileges.

Bạn có thể cấp đặc quyền đối tượng mà bạn được cấp bằng Grant Option. Nếu bạn là chủ nhân của đối tượng, bạn có thể cấp tất cả những đặc quyền trên đối tượng. Chọn những đặc quyền bạn muốn cấp cho đối tượng được chọn. Danh sách cuộn bao gồm những đặc quyền bạn có thể cấp trên đối tượng này.

Hộp Grant Option cho phép user cấp đặc quyền đối tượng cho những user và role khác.

Click Add để thêm những đặc quyền đối tượng được chọn cho user.

Available Privileges

Hiển thị những đặc quyền có giá trị cho đối tượng schema được chọn trong danh sách cây.

Up and Down Arrows

Down Arrow thêm những đặc quyền mà được chọn trong danh sách Available Privileges đến bản tính Granted Object Privileges

Up Arrow gỡ bỏ những đặc quyền mà được chọn trong bảng tính Granted Object Privileges.

Granted Object Privileges

Bảng tính có thể soạn thảo hiển thị những đặc quyền đối tượng được làm có giá trị cho user. Sự thêm mới (được chọn nhưng chưa được áp dụng) được nhận dạng bởi hand với ký hiệu dấu cộng.

Khi tạo user mới, bảng tính gồm có hai cột cho biết tên của đặc quyền đối tượng và có hoặc không có Grant Option được chỉ định đối với đặc quyền đó.

Khi được cho phép, Grant Option cho phép user cấp đặc quyền đối tượng cụ thể cho những user và role khác. Ngầm định, tùy chọn này bị vô hiệu hóa. Để cho phép tùy chọn grant, click vào mục nhập bảng tính cụ thể. "X" là chọn.

Khi tạo role, bảng tính gồm có chỉ một cột Object Privilege.

Thẻ thuộc tính Create User: trang Quotas

Trên trang Quotas của thẻ thuộc tính Create User, bạn có thể chỉ định những tablespace, user có thể chỉ định khoảng trống và số lượng khoảng trống lớn nhất mà user có thể chỉ định bên trong mọi tablespace. Trang này có giá trị trong chế độ Advanced. Trang Quotas chứa những mục sau:

Quota Details

Danh sách cuộn chứa những tablespace trong database và số lượng khoảng trống lớn nhất user được cho phép trong mọi tablespace. Danh sách có thể được sắp xếp dựa vào cột Tablespace hoặc kích thước Quota.

Để chỉ định kích thước quota cho tablespace, chọn tablespace trong danh sách cuộn và chỉ định kích thước quota bằng cách click vào nút None, Unlimited, hoặc Value.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> None
Click None nếu bạn không muốn user có bất kỳ quota trên tablespace được chọn.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Unlimited
Để chỉ định quota unlimited cho tablespace, click nút Unlimited. Với quota unlimited, user có thể chỉ định số lượng khoảng trống không có giới hạn trong tablespace.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Value
Để chỉ định quota cụ thể, click Value và nhập giá trị quota trong trường mục nhập văn bản bên cạnh. Chọn nút K hoặc M để chỉ định Kilobytes hoặc Megabytes.

Note:

Nếu user được cấp đặc quyền hệ thống UNLIMITED TABLESPACE, tùy chọn Quota Details bị vô hiệu hóa.

Tạo User giống nhau

Để tạo user mới với những thuộc tính tương tự như user hiện hữu:

Chọn Create Like từ menu User. Thẻ thuộc tính Create User xuất hiện với tất cả những thông số được chỉ định ngoại trừ trường Name.

Sửa đổi bất kỳ thông số thẻ thuộc tính cho user mới nếu như cần thiết.

Click Create.

Bạn cũng có thể thực hiện thao tác này bằng cách chọn user từ danh sách cây và sau đó chọn tùy chọn menu Create Like. Bạn phải nhập tên của user mới và nhập password mới nếu nút Password được chọn.

Dạng thức và nội dung của thẻ thuộc tính Create Like giống hệt thẻ thuộc tính Create User. Tham khảo đến Cách tạo User để biết thông tin về thẻ thuộc tính.

Sửa đổi User

Để thay đổi những đặc tính của user:

Chọn user từ danh sách cây để hiển thị thẻ thuộc tính chi tiết của user.

Sửa đổi những thông số thẻ thuộc tính nếu như cần thiết.

Click Apply.

Bạn cũng có thể hiển thị thẻ thuộc tính Quick Edit bằng cách chọn user từ danh sách multi-column và chọn Quick Edit từ menu ngữ cảnh di động. Thẻ thuộc tính Quick Edit giống hệt thẻ thuộc tính chi tiết.

Thẻ thuộc tính details/Quick Edit giống hệt dạng thức và nột dung thẻ thuộc tính Create User ngoại trừ trường name chỉ được đọc. Xem Cách tạo User để biết thêm thông tin về thẻ thuộc tính.

Suggestion: Nếu bạn muốn thêm những đặc quyền hoặc role cho nhiều user, sử dụng Add Privileges và Roles ở mục menu Users. Xem Thêm những đặc quyền hoặc Role cho User.

Attention: Nếu bạn sửa đổi đối tượng, như user tên là DAVE hoặc role tên là CLERK, ở bất kỳ vị trí nào trong danh sách cây, tất cả instances của đối tượng trong cây được thay đổi.

Gỡ bỏ User

Nếu bạn không cần user riêng biệt trong database của bạn nữa, bạn có thể gỡ bỏ user bằng cách chọn user được thả xuống từ thư mục Users trong danh sách cây và chọn Remove từ menu User. Hộp cảnh báo Remove User xuất hiện.

Hộp cảnh báo Remove User cho biết nếu user vẫn còn có bất kỳ những đối tượng. Nếu bạn gỡ bỏ user người mà có những đối tượng, Security Manager:

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Drop tất cả những đối tượng trong schema của user.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Drop bất kỳ những ràng buộc toàn vẹn có liên quan trong những schema khác mà tham chiếu đến những bảng của user bị drop.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Vô hiệu hoá bất kỳ view hoặc synonym dành cho những đối tượng trong schema của user bị drop.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Vô hiệu hoá bất kỳ những thủ tục, chức năng, hoặc những gói được lưu mà truy vấn những đối tượng trong schema của user bị drop.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Không drop snapshots trên những bảng hoặc view trong schema của user bị drop.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Không drop bất kỳ role được tạo bởi user.

Thêm những Đặc quyền hoặc Role cho User

Để thêm nhiều role và cấp nhiều đặc quyền hệ thống hoặc đối tượng cho những user:

Chọn Add Privileges to Users từ menu User hoặc một trong những menu ngữ cảnh di động. Hộp thoại Add Privileges to Users hiển thị cùng với danh sách cuộn chứa những user được hiển thị trong phân nửa đỉnh của hộp hội thoại.

Chọn những user trong danh sách mà bạn muốn thêm những đặc quyền hoặc role đến.

Chọn Roles, System Privileges, hoặc Object Privileges từ danh sách thả xuống Privilege Type. Sự hiển thị trong phân nửa dưới của hộp hội thoại thay đổi theo sự chọn lựa của bạn.

Click OK để cam kết những sự thay đổi bạn đã làm.

Roles

Nếu bạn đã chọn Roles, những role mà bạn có thể cấp cho user hiển thị trong danh sách cuộn. Đây là những role bạn đã tạo và những role bạn đã cấp bằng Admin Option. Nếu bạn có đặc quyền hệ thống GRANT ANY ROLE, tất cả role được liệt kê.

Chọn những role mà bạn muốn thêm cho những user được chọn.

Attention: Những role mà bạn thêm đến những user được gán như là những role ngầm định trừ khi bạn thay đổi đặc tả trên trang Default Roles của thẻ thuộc tính Alter cho mọi user.

Click hộp With Admin Option để cho phép user cấp role cho những user hoặc role khác. Nếu bạn cấp role bằng Admin Option, user cũng có thể sửa đổi hoặc drop role.

Bạn phải thêm những role với Admin Option bằng thao tác riêng lẻ từ những role bạn muốn thêm mà không có Admin Option.

Note: Khi bạn cấp role DBA và RESOURCE cho user hoặc role với Oracle7 release 7.2.2 hoặc cao hơn, user hoặc role cũng được cấp đặc quyền hệ thống UNLIMITED TABLESPACE. Khi bạn hủy bỏ role từ user hoặc role, đặc quyền hệ thống UNLIMITED TABLESPACE cũng được hủy bỏ. UNLIMITED TABLESPACE cũng có thể được hủy bỏ không phụ thuộc vào role DBA và RESOURCE.

Từ SQL Worksheet, sử dụng lệnh GRANT để cấp những đặc quyền trên cột trong table hoặc view.

System Privileges

Danh sách cuộn về những đặc quyền hệ thống mà bạn có thể cấp cho những user. Đây là những đặc quyền hệ thống bạn được cấp bằng Admin Option. Nếu bạn có đặc quyền hệ thống GRANT ANY PRIVILEGE, tất cả những đặc quyền được liệt kê.

Chọn những đặc quyền mà bạn muốn thêm đến những user được chọn. Click hộp With Admin Option để cho phép user cấp những đặc quyền cho những user hoặc role khác.

Attention:

Bạn phải thêm những đặc quyền với Admin Option bằng thao tác riêng lẻ từ những đặc quyền bạn muốn thêm mà không có Admin Option.

Object Privileges

Cây liệt kê những schema trong database và những đối tượng trong những schema hiển thị trong cửa sổ Object. Click vào '+' ở phía bên trái của biểu tượng thư mục kế để hiển thị những kiểu đối tượng được chứa trong schema và sau đó click vào '+' ở phía bên trái của thư mục kiểu đối tượng để hiển thị những đối tượng có giá trị. Chọn những đối tượng mà bạn muốn cấp những đặc quyền cho nó.

Sau khi đối tượng được chọn, những đặc quyền có giá trị cho đối tượng được hiển thị ở phía bên phải trong danh sách cuộn Privileges.

Bạn có thể cấp đặc quyền đối tượng mà bạn được cấp bằng Grant Option. Nếu bạn là chủ nhân của đối tượng, bạn có thể cấp tất cả những đặc quyền trên đối tượng. Chọn những đặc quyền bạn muốn cấp cho những đối tượng được chọn.

Attention: Bạn phải thêm những đặc quyền với Grant Option bằng thao tác riêng lẻ từ những đặc quyền bạn muốn thêm mà không có Grant Option.

Gỡ bỏ những đặc quyền hoặc Role từ User

Để gỡ bỏ những role hoặc đặc quyền mà được gán hiện thời đối với user:

Từ thư mục Users trong danh sách cây, click vào '+' ở phía bên trái của user để mở rộng Roles Granted, System Privileges Granted, và Object, click vào '+' ở phía bên trái của biểu tượng thư mục để hiển thị những đặc quyền hoặc role mà đã cấp cho user.

Chọn đặc quyền hoặc role mà bạn muốn gỡ bỏ từ user.

Chọn Revoke Privilege từ menu User hoặc Revoke từ menu ngữ cảnh di động để gỡ bỏ đặc quyền hoặc role được chọn từ user.

Danh sách Multi-Column về những đặc quyền

Danh sách cuộn multi-column về những đặc quyền hiển thị khi thư mục kiểu đối tượng Roles Granted, System Privileges Granted hoặc Object Privileges Granted được chọn trong danh sách cây. Danh sách chứa thông tin vế những đặc quyền được gán cho user hoặc role.

Roles Granted

Những cột trong danh sách Roles Granted bao gồm:

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Role
Tên của role.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Admin option
Có hoặc không có role được cấp bằng Admin option cho user hoặc role.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Default
Cho biết role là ngầm định cho user trong lúc đăng nhập hệ thống.

System Privileges Granted

Những cột trong danh sách System Privileges Granted bao gồm:

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> System Privilege
Tên của đặc quyền hệ thống.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Admin Option
Có hoặc không có đặc quyền được cấp bằng Admin option cho user hoặc role.

Object Privileges Granted

Những cột trong danh sách Object Privileges Granted bao gồm:

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Object Privilege
Tên của đặc quyền đối tượng.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Grant option
Có hoặc không có đặc quyền được cấp bằng Grant option cho user.

Đế biết thêm thông tin về những cột này, xem mô tả về thẻ thuộc tính Create User trong phần, Cách tạo User.

Thư mục Roles

Thư mục kiểu đối tượng Roles chứa thông tin về những role được định nghĩa trong database của bạn được sắp xếp theo thức thự alphabe trong cấu trúc cây. Role riêng lẻ có thể được mở rộng để trình bày những đặc quyền hệ thống, những đặc quyền đối tượng, và những role được cấp đến role.

Khi bạn chọn:

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> thư mục Roles, danh sách multi-column hiển thị những role và sự xác nhận có giá trị, nếu cần thiết.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> role riêng lẻ, thẻ thuộc tính Roles hiển thị những sự thiết lập chi tiết cho role.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> thư mục Roles Granted, System Privileges Granted, hoặc Object Privileges Granted ở dưới role riêng lẻ, danh sách multi-column về những đặc quyền hoặc role được cấp cho role hiển thị. Xem Danh sách Multi-Column về những đặc quyền.

Những role được đặt tên là những group gồm có những đặc quyền được cấp cho những user hoặc những role khác.

0_s1034" width="17" border="0" height="16" /> Danh saùch Multi-Column Roles
0_s1035" width="17" border="0" height="16" /> Caùch taïo Role
0_s1036" width="17" border="0" height="16" /> Taïo Role gioáng nhau
0_s1037" width="17" border="0" height="16" /> Caùch söûa ñoåi Role
0_s1038" width="17" border="0" height="16" /> Caùch gôõ boû Role
0_s1039" width="17" border="0" height="16" /> Caùch theâm nhöõng ñaëc quyeàn hoaëc Role cho Roles
0_s1040" width="17" border="0" height="16" /> Caùch gôõ boû nhöõng ñaëc quyeàn hoaëc Role töø Roles

Danh sách Multi-Column Roles

Danh sách multi-column roles hiển thị khi thư mục Roles hoặc Roles Granted được chọn trong danh sách cây. Danh sách cuộn multi-column chứa một hàng thông tin tóm tắt cho mọi role trong thư mục roles.

Nếu thư mục tên là Roles Granted và được chứa trong user hoặc role, danh sách chỉ chứa thông tin về những role được gán cho use hoặc role. Những cột của danh sách multi-column Roles gồm có:

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Role
Tên của role.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Authentication
Kiểu xác nhận được sử dụng: none, external, password, hoặc global.

Để biết thêm thông tin về những cột này, xem mô tả về thẻ thuộc tín Create User trong phần, Cách tạo User.

Suggestion:

Nếu danh sách multi-column mà lớn hơn vùng hiển thị của cửa sổ, bạn có thể tăng thêm vùng xem bằng cách thay đổi kích thước cửa sổ ứng dụng hoặc kéo vạch ngăn cách giữa phần bên trái và bên phải của của sổ.

Cách tạo Role

Để tạo role mới:

Chọn Create từ menu Role hoặc một trong những menu ngữ cảnh di động. Trang General của thẻ thuộc tính Create Role xuất hiện.

Điền vào trong thẻ thuộc tính với những thông số được yêu cầu.

Click nút Create để áp dụng những sự thay đổi bạn đã làm với thẻ thuộc tính và tạo role mới.

Thẻ thuộc tính Create Role chứa những trang sau.

General (Basic UI mode)

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Roles/Privileges (Xem Thẻ thuộc tính Create User: Roles/Privileges)

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Object Privileges (Xem Thẻ thuộc tính Create User: Object Privileges)

Thẻ thuộc tính Create Role: Trang General

Trang này cho phép bạn nhập thông tin sau:

Role

Tên của role để được tạo. Nhập tên của role mới.

Authentication

Phương thức được sử dụng để cho phép role.

None: Chỉ định rằng user được cấp role có thể cho phép nó không chỉ định password.

Global: Chỉ định rằng user được cấp role có thể cho phép nó là toàn cục trong số nhiều database. Tùy chọn sự cho phép toàn cục chỉ có giá trị đối với Oracle 8 databases.

External: Chỉ định rằng hệ điều hành hoặc tiện ích security external xác nhận role.

Password: Chỉ định rằng password được yêu cầu để cho phép role. Nhập password trong trường mục nhập Enter Password. Nhập password lần nữa trong trường mục nhập Confirm Password để xác minh password mới.

Tạo Role giống nhau

Nếu bạn muốn tạo role mới cùng với những thông số tương tự như role hiện hữu:

Chọn role mong muốn từ danh sách cây.

Chọn tùy chọn menu Create Like từ menu Role.

Sửa đổi thẻ thuộc tính như mong muốn.

Click nút Create.

Bạn cũng có thể thực hiện thao tác này bằng cách chọn role trong danh sách cây và chọn tùy chọn menu Create Like từ menu ngữ cảnh di động. Bạn phải nhập tên của role mới và nhập password mới nếu nút Password được chọn.

Thẻ thuộc tính này giống hệt thẻ thuộc tính Create Role. Tham khảo Cách tạo User để biết thông tin về thẻ thuộc tính Create Role.

Cách sửa đổi Role

Để sửa đổi thông tin thẻ thuộc tính đối với role hiện hữu:

Chọn role cần sử đổi từ danh sách cây. Thẻ thuộc tính đối với role đó xuất hiện.

Sửa đổi thẻ thuộc tính như mong muốn.

Click nút Apply.

Bạn cũng có thể sửa đổi role bằng cách chọn role từ danh sách multi-column Role cùng với right-click để gọi menu ngữ cảnh di động lên. Chọn Quick Edit đưa ra thẻ thuộc tính Quick Edit xuất hiện.

Thẻ thuộc tính Role giống hệt thẻ thuộc tính Create Role ngoại trừ là trường tên chỉ đọc. Tham khảo Cách tạo User để biết thông tin về thẻ thuộc tính.

Nếu bạn muốn thêm những đặc quyền hoặc role cho nhiều role, sử dụng Add Privileges từ mục menu Roles. Xem Cách thêm những đặc quyền hoặc Role cho Role.

Nếu bạn sửa đổi đối tượng, như user tên là DAVE hoặc role tên là CLERK, trong bất kỳ vị trí nào của danh sách cây, tất cả instances của đối tượng trong danh sách cây cũng được thay đổi.

Cách gỡ bỏ Role

Để gỡ bỏ role mà không cần nữa:

Chọn role trong danh sách cây.

Chọn Remove từ menu Role. Hộp cảnh báo Remove Role xuất hiện.

Click Yes để gỡ bỏ role.

Bạn cũng có thể gỡ bỏ role bằng cách chọn role được thả từ thư mục kiểu đối tượng Roles trong danh sách cây và chọn Remove từ menu ngữ cảnh di động.

Cách thêm những đặc quyền hoặc Role cho Roles

Để gán những role con (subrole) và cấp những đặc quyền riêng lẻ cho nhiều role, hoặc thêm những role và cấp những đặc quyền cho nhiều role:

Chọn Add Privileges to Roles từ menu Role để hiển thị hộp hội thoại Add Privileges to Roles. Danh sách cuộn của role được hiển thị ở phân nửa đỉnh của hộp hội thoại.

Chọn những role trong danh sách mà bạn muốn thêm những đặc quyền hoặc role đến.

Chọn System Privileges, Object Privileges, hoặc Roles từ danh sách drop-down. Sự hiển thị ở phân nửa dưới của hộp hội thoại thay đổi theo sự chọn lựa của bạn.

Roles

Nếu bạn đã chọn Roles, roles mà bạn có thể cấp cho role hiển thị trong danh sách cuộn. Đây là những role bạn đã tạo và những role bạn được cấp bằng Admin Option. Nếu bạn có đặc quyền hệ thống GRANT ANY ROLE, tất cả role được liệt kê.

Chọn những role mà bạn muốn thêm cho role.

Click hộp With Admin Option để cho phép role cấp role cho những user hoặc role khác. Nếu bạn cấp role bằng Admin Option, role cũng có thể sử đổi hoặc drop role.

Click nút Apply để thêm những role được chọn cho role.

Attention:

Bạn phải thêm những role bằng Admin Option với thao tác riêng lẻ từ những role bạn muốn thêm mà không có Admin Option.

System Privileges

Danh sách cuộn của những đặc quyền hệ thống mà bạn có thể cấp cho role. Đây là những đặc quyền hệ thống bạn được cấp bằng Admin Option. Nếu bạn có đặc quyền hệ thống GRANT ANY PRIVILEGE, tất cả những đặc quyền được liệt kê.

Chọn những đặc quyền mà bạn muốn thêm cho role.

Click hộp With Admin Option để cho phép role cấp những đặc quyền hệ thống cho những user hoặc role khác.

Click nút Add để thêm những đặc quyền hệ thống được chọn cho role.

Attention:

Bạn phải thêm những đặc quyền bằng Admin Option với thao tác riêng lẻ từ những đặc quyền bạn muốn thêm mà không có Admin Option.

Object Privileges

Cây liệt kê những schema trong database và những đối tượng bên trong những schema hiển trị trong cửa sổ Object. Click vào '+' ở phía bên trái của biểu tượng thư mục để hiển thị những đối tượng được chứa trong schema, sau đó chọn những đối tượng mà bạn muốn cấp những đặc quyền cho nó.

Sau khi đối tượng được chọn, những đặc quyền có giá trị đối với đối tượng được hiển thị ở phía bên phải trong danh sách cuộn Privileges.

Chọn những đặc quyền bạn muốn cấp cho đối tượng được chọn. Danh sách cuộn bao gồm những đặc quyền đối tượng bạn có thể cấp trên object.

Click nút Apply để thêm những đặc quyền đối tượng được chọn cho role.

Click vào nút Apply để lưu bất kỳ những sự thay đổi nào bạn đã làm trong hộp hội thoại.

Cách gỡ bỏ những đặc quyền hoặc Role từ Roles

Để gỡ bỏ những đặc quyền hoặc subroles mà được gán cho role trong thư mục Roles:

Từ danh sách cây, chọn đặc quyền hoặc subrole mà bạn muốn gỡ bỏ từ role. Nếu cần thiết, click vào '+' ở phía bên trái của biểu tượng thư mục để hiển thị những đặc quyền hoặc subroles mà đã được gán cho role.

Chọn Remove từ menu Role.

Để gở bỏ nhiều đặc quyền hoặc subroles thuận tiện từ chỉ một role, sử dụng thẻ thuộc tính thích hợp.

Thư mục Profiles

Thư mục Profiles chứa thông tin về những profiles được định nghĩa cho database xắp xếp theo thứ tự alphabe trong cấu trúc cây. Profile riêng lẻ có thể được mở rộng để hiện những user mà được gán profile.

Khi bạn chọn:

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> thư mục kiểu đối tượng Profiles, danh sách multi-column hiển thị một hàng thông tin tóm tắt cho mọi profiles trong database.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> profile riêng lẻ, thẻ thuộc tính soạn thảo hiển thị những thiết lập chi tiết đối với profile.

Profile thiết lập những giới hạn trên những tài nguyên database. Khi bạn gán profile cho user, user đó không có thể vượt quá những giới hạn đã thiết lập trong profile.

Oracle tư động tạo profile ngầm định tên là DEFAULT. Profile DEFAULT ban đầu định nghĩa những tài nguyên không giới hạn. Bạn có thể sửa đổi profile DEFAULT để thay đổi bất kỳ những giới hạn tài nguyên của nó.

Bất kỳ user người mà không được gán profile rõ ràng thì tùy thuộc vào những giới hạn được định nghĩa trong profile DEFAULT. Hơn nữa, nếu profile mà được gán cho user bỏ sót giới hạn về tài nguyên hoặc chỉ định giá trị DEFAULT cho giới hạn, khi đó user tùy thuộc vào giới hạn trên tài nguyên đó như định nghĩa trong profile DEFAULT.

Attention:

Thông số khởi tạo RESOURCE_LIMIT phải thiết lập bằng TRUE để làm cho những giới hạn thiết lập trong những profile database có hiệu lực.

0_s1041" width="17" border="0" height="16" /> Danh saùch Multi-Column Profile
0_s1042" width="17" border="0" height="16" /> Caùch taïo Profile
0_s1043" width="17" border="0" height="16" /> Taïo Profile gioáng nhau
0_s1044" width="17" border="0" height="16" /> Caùch söûa ñoåi Profile
0_s1045" width="17" border="0" height="16" /> Caùch theâm nhöõng Profile phuï thuoäc vaø phaàn phuï thuoäc
0_s1046" width="17" border="0" height="16" /> Caùch gôõ boû Profile
0_s1047" width="17" border="0" height="16" /> Caùch gaùn Profile cho nhöõng User

Danh sách Multi-Column Profile

Danh sách multi-column profiles hiển thị khi thư mục Profiles được chọn trong dánh sách cây. Danh sách cuộn chứa một hàng thông tin tóm tắt cho mọi profile trong thư mục Profiles.

Những cột bao gồm tất cả những trường trên những trang của thẻ thuộc tính Create Profile. Để biết thêm thông tin về những cột này, xem Cách tạo Profile.

Cách tạo Profile

Để tạo profile:

Chọn Create từ menu Profile.Thẻ thuộc tính Create Profile xuất hiện. Thẻ thuộc tính này chứa trang General và Password.

Thẻ thuộc tính Create Profile: trang General

Name

Trường này cho phép bạn nhập tên của profile mới.

Details

Những trường này xác định tổng số thời gian phân phát CPU cho mọi phiên, CPU cho mọi sự yêu cầu (call), thời gian kết nối, và thời gian nhàn rỗi cho profile này. Những trường này là:

CPU/Session: Số lượng thời gian CPU tổng cộng được phân phát theo phiên. Giới hạn được biểu diễn theo giây.

CPU/Call: Số lượng thời gian CPU lớn nhất được phân phát cho sự yêu cầu (call) (phân tách, thực thi, hoặc tìm nạp (fetch)). Giới hạn được biểu diễn theo giây.

Connect Time: Thời gian trôi qua lớn nhất được phân phát cho phiên. Giới hạn được biểu diễn theo giây.

Idle Time: Thời gian nhàn rỗi lớn nhất được phân phát theo phiên. Thời gian nhàn rỗi là chu kỳ thời gian không hoạt động liên tục trong phiên. Những câu truy vấn đòi hỏi thời gian thực thi dài và những thao tác khác không tùy thuộc vào giới hạn này. Giới hạn được biểu diễn theo phút.

Bạn có thể nhập giá trị trong trường hoặc chọn từ danh sách drop-down bên cạnh trường. Click vào down-arrow để hiển thị danh sách. Danh sách drop-down cung cấp những sự chọn lựa sau:

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Database Services
Những trường này xác định những dịch vụ database được phân phát cho profile này. Những trường này là:

Concurrent Sessions: Số phiên xảy ra đồng thời lớn nhất được phân phát cho user.

Reads/Session: Số thời gian dành để đọc data block tổng cộng được phân phát theo phiên. Giới hạn bao gồm những block được đọc từ bộ nhớ và đĩa.

Reads/Call: Số thời gian dành để đọc data block lớn nhất được phân phát cho sự yêu cầu (call) (phân tách, thực thi, hoặc tìm ra (fetch)) để xử lý câu lệnh SQL.

Private SGA: Số lượng khoảng trống riêng lớn nhất mà phiên có thể chia phần trong vốn dùng chung của vùng hệ thống toàn cục (System Global Area: SGA). Giới hạn SGA riêng chỉ áp dụng nếu bạn sử dụng cấu trúc server multi-threaded. Giới hạn được biểu diễn theo kilo bytes (KBytes).

Composite Limit: Giá tài nguyên tổng cộng dành cho phiên. Giá tài nguyên dành cho phiên là tổng số trọng lượng về thời gian CPU được sử dụng trong phiên, thời gian kết nối, số lần đọc được làm trong session, và số lượng khỏang trống SGA riêng được phân phát.

Bạn có thể nhập giá trị trong trường hoặc chọn từ danh sách drop-down bên cạnh trường. Click vào down-arrow để hiển thị danh sách. Danh sách drop-down cung cấp những sự chọn lựa sau:

Attention:

Trong SQL Worksheet, bạn có thể sử dụng lệnh ALTER RESOURCE COST của SQL để chỉ định trọng lượng cho tài nguyên trong Composite Limit.

t-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> Drop-down List Selections
Default: Sử dụng giới hạn được chỉ định cho tài nguyên này trong profile DEFAULT.

Unlimited: Sự truy xuất của user đến tài nguyên này là không giới hạn.

Values: Chọn một trong những giá trị có sẵn. Những giá trị ngầm định biến đổi bởi trường và những giá trị phổ biến cho trường. Nếu bạn đã nhập giá trị trong trường, giá trị đó xuất hiện trong danh sách drop-down.

Thẻ thuộc tính Create Profile: trang Password (Oracle 8)

Trang Password cho phép bạn thiết lập những thông số password tài khoản. Trang này gồm có những mục sau:

Expire Password

Expire in: Giới hạn số ngày sau mà password hết hiệu lực. Chọn giá trị từ danh sách drop-down, hoặc nhập giá trị cụ thể.

Lock: Giới hạn số ngày trong lúc mà password có thể được thay đổi sau lần đăng nhập thành công đầu tiên sau đó password hết hiệu lực.

Keep Password History

Keep: Chỉ định số thời gian password phải được thay đổi trước khi nó có thể được dùng lại. Keep for bị vô hiệu hoá nếu một giá trị được chỉ định trong trường này.

Keep for: Giới hạn số ngày trước khi password có thể được dùng lại sau khi nó hết hiệu lực. Keep bị vô hiệu hoá nếu một giá trị được chỉ định trong trường này.

Enforce Password Complexity

Cho phép tập tin thi hành PL/SQL được sử dụng dành cho sự xách minh password khi những user người mà được gán profile này đăng nhập vào database. Tập tin thi hành PL/SQL này phải có giá trị cho sự thi hành cục bộ trên database mà profile này áp dụng.

Oracle cung cấp script ngầm định (utlpwdmg.sql), tuy nhiên, bạn cũng có thể tạo ra tập tin thi hành của chính bạn, hoặc sử dụng phần mềm third-party như là sự lựa chọn. Tập tin thi hành sự xách minh password phải được làm chủ bởi SYS.

NULL (không có sự xác minh password) thiết lập ngầm định.

Lock account on failed logon

Lock after: Giới hạn số lần sự thử đăng nhập thất bại được cho phép trước khi user bị khoá tài khoản.

Lock for: Chỉ định số ngày tài khoản bị khóa lại sau khi thất bại bởi số ngày sự thử đăng nhập được chỉ định. Nếu UNLIMITED được chọn, chỉ người quản trị database có thể mở khoá tài khoản.

Note: Nếu Default được chọn đối với bất kỳ sự tùy chọn password nào, những giá trị được định nghĩa trong profile Default được sử dụng.

Tạo Profile giống nhau

Để tạo profile mới mà có những thiết lập thông số giống hệt với profile hiện có:

Chọn profile muốn được sao chép từ danh sách cây.

Chọn Create Like từ menu Profile. Thẻ thuộc tính Create Profile xuất hiện.

Chỉ định tên profile và sử đổi những thông số thẻ thuộc tính nếu cần thiết.

Click nút Create.

Bạn cũng có thể thực hiện thao tác này bằng cách chọn profile từ cây hoặc danh sách multi-column và chọn tùy chọn menu Create Like. Bạn phải nhập tên của profile mới.

Thẻ thuộc tính Create Like giống hệt thẻ thuộc tính Create Profile. Xem Cách tạo Profile để biết thông tin về thẻ thuộc tính.

Cách sửa đổi Profile

Để sửa đổi những giới hạn tài nguyên đối với profile hiện có:

Chọn profile muốn sửa đổi từ danh sách cây. Thẻ thuộc tính Profile xuất hiện.

Sửa đổi những giới hạn tài nguyên nếu cần thiết.

Click nút Apply.

Bạn cũng có thể sử dụng thẻ thuộc tính Quick Edit để sửa đổi profile bằng cách chọn profile từ danh sách multi-column sử dụng right-click và chọn Quick Edit từ menu ngữ cảnh di động.

Thẻ thuộc tính Quick Edit giống hệt thẻ thuộc tính Create Profile ngoại trừ là trường name chỉ đọc. Xem Cách tạo Profile để biết thông tin về thẻ thuộc tính.

Trong SQL Worksheet, bạn có thể sử dụng lệnh ALTER RESOURCE COST của SQL để chỉ định trọng lượng cho những tài nguyên trong Composite Limit.

Cách thêm những Profile phụ thuộc và phần phụ thuộc

Để hiển thị những sự phụ thuộc cho profile riêng biệt:

Chọn profile từ danh sách cây.

Chọn Show Dependencies từ menu Profiles.

Những phần phụ thuộc được tổ chức bởi user. Mở rộng những user riêng lẻ trong Dependencies Viewer hiển thị những đối tượng schema, những role, và những privilege được kết hợp với user đó.

Cách gỡ bỏ Profile

Để gỡ bỏ profile mà không cần nữa:

Chọn profile muốn xóa từ danh sách cây.

Chọn Remove từ menu Profile. Hộp cảnh báo Remove Profile xuất hiện.

Hộp cảnh báo Remove Profile cho biết nếu profile bạn muốn drop được gán cho bất kỳ user nào. Nếu bạn drop profile mà được gán cho những user, Security Manager gán profile DEFAULT cho những user đó.

Click OK.

Note: Bạn không có thể drop profile DEFAULT.

Cách gán Profile cho những User

Để gán profile cho nhiều user trong database:

Chọn tùy chọn menu Assign Profile to Users từ menu Profile. Hộp hội thoại Assign Profile xuất hiện.

Chọn profile mà bạn muốn gán từ danh sách drop-down.

Trong danh sách cuộn, chọn những user mà bạn muốn gán profile đến.

Click nút Apply để gán profile được chọn cho user(s). Bạn có thể click OK để gán profile và đóng hộp hội thoại.