InterSystems SQL提供了一个特殊的–>
运算符,作为从相关表中获取值的快捷方式,而在某些常见情况下无需指定显式的JOIN
即可。可以使用此箭头语法代替显式联接语法,也可以将其与显式联接语法结合使用。箭头语法执行左外部联接。
箭头语法可用于类的属性或父表的关系属性的引用。其他类型的关系和外键不支持箭头语法。不能在ON
子句中使用箭头语法(–>
)。
可以使用- >
操作符作为从“引用表”
获取值的简写。
例如,假设定义了两个类:Company
:
Class Sample.Company Extends %Persistent [DdlAllowed]
{
/// The Company name
Property Name As %String;
}
Employee
:
Class Sample.Employee Extends %Persistent [DdlAllowed]
{
/// The Employee name
Property Name As %String;
/// The Company this Employee works for
Property Company As Company;
}
Employee
类包含一个属性,该属性是对Company
对象的引用。
在基于对象的应用程序中,可以使用点语法遵循此引用。
例如,要查找Employee
工作的Company
名称:
Set name = employee.Company.Name
可以使用使用外部连接来连接Employee
和Company
表的SQL语句来执行相同的任务:
SELECT Sample.Employee.Name, Sample.Company.Name AS CompName
FROM Sample.Employee LEFT OUTER JOIN Sample.Company
ON Sample.Employee.Company = Sample.Company.ID
使用- >
操作符,可以更简洁地执行相同的外连接操作:
SELECT Name, Company->Name AS CompName
FROM Sample.Employee
只要在表中有引用列,就可以使用–>
运算符;也就是说,其列的值是被引用表的ID(本质上是外键的特殊情况)。在这种情况下,Sample.Employee
的Company
字段包含Sample.Company
表中记录的ID
。可以在可以在查询中使用列表达式的任何地方使用–>
运算符。例如,在WHERE
子句中:
SELECT Name,Company AS CompID,Company->Name AS CompName
FROM Sample.Employee
WHERE Company->Name %STARTSWITH 'G'
使用–>
运算符,可以更简洁地执行相同的OUTER JOIN
操作:
这等效于:
SELECT E.Name,E.Company AS CompID,C.Name AS CompName
FROM Sample.Employee AS E, Sample.Company AS C
WHERE E.Company = C.ID AND C.Name %STARTSWITH 'G'
请注意,在这种情况下,此等效查询使用INNER JOIN
。
以下示例使用箭头语法访问Sample.Person
中的“Spouse”
字段。如示例所示,Sample.Employee
中的Spouse
字段包含Sample.Person
中记录的ID
。本示例返回Employee
与其Spouse
的Home_State
相同的Home_State
或Office_State
的那些记录:
SELECT Name,Spouse,Home_State,Office_State,Spouse->Home_State AS SpouseState
FROM Sample.Employee
WHERE Home_State=Spouse->Home_State OR Office_State=Spouse->Home_State
可以在GROUP BY
子句中使用–>运算符:
SELECT Name,Company->Name AS CompName
FROM Sample.Employee
GROUP BY Company->Name
可以在ORDER BY
子句中使用–>
运算符:
SELECT Name,Company->Name AS CompName
FROM Sample.Employee
ORDER BY Company->Name
或在ORDER BY
子句中为–>
运算符列引用列别名:
SELECT Name,Company->Name AS CompName
FROM Sample.Employee
ORDER BY CompName
支持复合箭头语法,如以下示例所示。在此示例中,Cinema.Review
表包含“Film”
字段,其中包含Cinema.Film
表的行ID
。 Cinema.Film
表包含Category
字段,其中包含Cinema.Category
表的行ID
。因此,Film-> Category-> CategoryName
访问以下三个表,以返回具有ReviewScore
的每部电影的CategoryName
:
SELECT ReviewScore,Film,Film->Title,Film->Category,Film->Category->CategoryName
FROM Cinema.Review
ORDER BY ReviewScore
可以使用–>
运算符来引用子表。例如,如果LineItems
是Orders
表的子表,则可以指定:
SELECT LineItems->amount
FROM Orders
请注意,在Orders
中没有称为LineItems
的属性。 LineItems
是包含数量字段的子表的名称。该查询在结果集中为每个Order
行生成多个行。它等效于:
SELECT L.amount
FROM Orders O LEFT JOIN LineItems L ON O.id=L.custorder
其中ustust
是LineItems
表的父引用字段。
使用箭头语法时,必须对两个表中的引用数据都具有SELECT
权限。必须在被引用的列上具有表级SELECT
权限或列级SELECT
权限。使用列级权限,需要对被引用表以及被引用列的ID具有SELECT
权限。
以下示例演示了所需的列级权限:
SELECT Name,Company->Name AS CompanyName
FROM Sample.Employee
GROUP BY Company->Name
ORDER BY Company->Name
在上面的示例中,必须对Sample.Employee.Name
,Sample.Company.Name
和Sample.Company.ID
具有列级SELECT
权限:
// d ##class(PHA.TEST.SQL).arrow()
ClassMethod arrow()
{
SET tStatement = ##class(%SQL.Statement).%New()
SET privchk1="%CHECKPRIV SELECT (Name,ID) ON Sample.Company"
SET privchk2="%CHECKPRIV SELECT (Name) ON Sample.Employee"
CompanyPrivTest
SET qStatus = tStatement.%Prepare(privchk1)
IF qStatus'=1 {
WRITE "%Prepare 失败:"
DO $System.Status.DisplayError(qStatus)
QUIT
}
SET rset = tStatement.%Execute()
IF rset.%SQLCODE=0 {
WRITE !,"拥有Company权限",!
} ELSE {
WRITE !,"无权限: SQLCODE=",rset.%SQLCODE,!
}
EmployeePrivTest
SET qStatus = tStatement.%Prepare(privchk2)
IF qStatus'=1 {
WRITE "%Prepare 失败:"
DO $System.Status.DisplayError(qStatus)
QUIT
}
SET rset = tStatement.%Execute()
IF rset.%SQLCODE=0 {
WRITE !,"拥有Employee权限",!
} ELSE {
WRITE !,"无权限: SQLCODE=",rset.%SQLCODE
}
}
DHC-APP>d ##class(PHA.TEST.SQL).arrow()
拥有Company权限
拥有Employee权限
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。