This Question and Answer Set includes the following topics:
読み取り専用のクラスやテーブルを作成するには、どのようにすればいいでしょうか?
ユーザがテーブルを編集する必要がない場合、抽象クラスとしてクラスをマークすることができます。 そうすれば、そのクラスは読み取り専用としてコンパイルされます。
一部のユーザがテーブルを編集し、すべてのユーザがテーブルから読み取ることができるようにする場合は、以下を実行します。
GRANT SELECT ON * TO PUBLIC.
これは、新規のテーブルを作成するたびに実行する必要があります。
一部のユーザが、すべてのテーブルに読み取りアクセスが必要な場合は、以下を実行します。
GRANT SELECT ON * TO Select_Role
次にアクセスが必要なユーザに対して、GRANT を使用して Select_Role を与えます。これは、新規のテーブルを作成するたびに実行する必要があります。
常に新規のテーブルが作成されている場合、この GRANT コードをストアド・プロシージャなどに入れると、呼び出しが簡単になります。自動的にテーブルを作成しているユーザは、そのテーブルのすべての権限を持つことに注意してください。
現在、以下のように MS SQL Server から Caché にストアド・プロシージャを移植する作業を行っています (以下のコードは簡素化しています)。
CREATE PROCEDURE UpdateName
@LastName varchar(35),
@FirstName varchar(25),
@NewKey int OUTPUT
AS
INSERT INTO NameTable (LastName, FirstName)
VALUES @LastName, @FirstName
SELECT @NewKey = @@Identity
この例が SQL Server で自動増分列を使用しているのと同じ方法で、独自の ID 列を使用したいのですが、挿入後に ID 列の値を抽出する方法が分かりません。また、出力パラメータの設定方法も教えてください。
DDL Create Procedure 文などを使用して、行うことができます。
CREATE PROCEDURE UpdateName(
INOUT pHandle %SQLProcContext,
LastName VARCHAR(35),
FirstName VARCHAR(25),
OUT NewKey INT)
LANGUAGE COS
{
Set NewKey=""
&sql(INSERT INTO NameTable (LastName, FirstName)
VALUES :LastName, :FirstName)
// %ROWID special variable contains the value of the ID column created
If 'SQLCODE Set NewKey=%ROWID
If $Get(pHandle)'=$$$NULLOREF
Set pHandle.SQLCode=SQLCODE,pHandle.RowCount=%ROWCOUNT
QUIT
}
顧客と注文の間に、親子リレーションシップを設定しています。 最新の注文と注文合計を見たいので、以下のクエリを使用しました。
SELECT ID, Name,
MAX(Order->Date),
SUM(Order->TotalAmount)
FROM Sales.Customer
Date と TotalAmount は、(子の) Order テーブルの列です。これでほぼ正しく作動し適切な値が取得できますが、1 人の顧客が複数の注文をした場合でも、1 つの注文ごとに別の顧客とみなしてしまいます。顧客 1 人あたりの Max (最大値) や Sum (合計値) を得るには、どうすればよいでしょうか?
あなたは実質的に親テーブルと子テーブルを結合し、SQL への Caché 拡張機能を使用して、結合に基づいたクエリ処理を行っているので、ご使用のクエリはあなたが要求した通りの結果を返しています (-> 構文を使用しないとしても、標準 SQL ではこのクエリは不正です)。あなたは顧客ごとの最新の注文と合計数を要求していますが、このクエリでは実際には正しい答えを返すことができません。このクエリが返す結果は、最新の注文とすべての顧客に対する合計であり、これが顧客の注文ごとに繰り返されます。あなたが得ようとするデータを求めるには、以下のようにいくつか方法があります。
SELECT ID, Name,
MAX(Order->Date),
SUM(Order->TotalAmount)
FROM Sales.Customer
GROUP BY Customer.ID
標準 SQL を使用すると、以下のようになります。
SELECT P.ID, P.Name,
(SELECT MAX(C.Date)
FROM Sales.Order AS C
WHERE C.CustomerID = P.ID),
(SELECT SUM(C.TotalAmount)
FROM Sales.Order AS C
WHERE C.CustomerID = P.ID)
FROM Sales.Customer AS P
以下も使用できます (これも標準 SQL を使用しています)。
SELECT ID, Name,
MAX(Order.Date),
SUM(Order.TotalAmount)
FROM Sales.Customer, Sales.Order
WHERE customer.id = Order.CustomerID
GROUP BY Customer.ID