这如何创建视图代码?

时间:2017-08-08 19:18:17

标签: sql sql-server tsql common-table-expression

好的,这里是视图的示例代码。 select RT.RoleID[...]的第二部分对我来说似乎很清楚。这是在运行查询以使用视图时将显示的部分。第一部分虽然不清楚。

我理解前两行是标准的,然后是整个with部分。有人可以向我解释一下吗?从未见过with "something" as (select)公式

    CREATE VIEW [dbo].[sviw_System_MyPermissions_CurrentDomain]
AS  

WITH MyDomainRoles AS (
  SELECT RM.Domain, RM.RoleID
    FROM stbl_System_RolesMembersDomains AS RM WITH (NOLOCK)
    WHERE RM.Domain = (SELECT CurrentDomain FROM stbl_System_Users WITH (NOLOCK) WHERE Login = SUSER_SNAME())
      AND RM.Login = SUSER_SNAME()
)

SELECT RT.RoleID, RT.TableName, DR.Domain, RT.GrantUpdate, RT.GrantInsert, RT.GrantDelete
  FROM stbl_System_RolesTables AS RT WITH (NOLOCK) 
    JOIN MyDomainRoles AS DR ON RT.RoleID = DR.RoleID

GO

2 个答案:

答案 0 :(得分:2)

它被称为Common Table Expresion,基本上你的观点与:

相同
CREATE VIEW vSalesStaffQuickStats
AS
 SELECT E.EmployeeID, 
         EmployeeOrders = OS.NumberOfOrders, 
         EmployeeLastOrderDate = OS.MostRecentOrderDate, 
         E.ManagerID, 
         ManagerOrders = OM.NumberOfOrders, 
         ManagerLastOrderDate = OM.MostRecentOrderDate 
  FROM   HumanResources.Employee AS E 
       INNER JOIN    (
            SELECT SalesPersonID, COUNT(*) NumberOfOrders
                  , MAX(OrderDate) MostRecentOrderDate
            FROM Sales.SalesOrderHeader
            GROUP BY SalesPersonID
      ) AS OS 
         ON E.EmployeeID = OS.SalesPersonID 
       LEFT OUTER JOIN    (
            SELECT SalesPersonID, COUNT(*) NumberOfOrders
                 , MAX(OrderDate) MostRecentOrderDate
            FROM Sales.SalesOrderHeader
            GROUP BY SalesPersonID
      ) AS OM 
         ON E.ManagerID = OM.SalesPersonID 

如您所见,您可以轻松地将其与子查询交换。但在你的情况下,你需要做两次(使用CTE你只做一次)。

修改

更新后使用新查询:

CREATE VIEW [dbo].[sviw_System_MyPermissions_CurrentDomain]
AS  
SELECT RT.RoleID, RT.TableName, DR.Domain, RT.GrantUpdate, RT.GrantInsert, RT.GrantDelete
FROM stbl_System_RolesTables AS RT WITH (NOLOCK) 
JOIN (
    SELECT RM.Domain, RM.RoleID
    FROM stbl_System_RolesMembersDomains AS RM WITH (NOLOCK)
    WHERE RM.Domain = (SELECT CurrentDomain FROM stbl_System_Users WITH (NOLOCK) WHERE Login = SUSER_SNAME())
      AND RM.Login = SUSER_SNAME()
) AS DR ON RT.RoleID = DR.RoleID

答案 1 :(得分:0)

WITH关键字只引用公用表表达式(在此处阅读更多内容:https://docs.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expression-transact-sql)基本上,WITH语句中的所有内容都可以视为外部化子查询,然后在主查询中使用结果集。

即:

const CACHE_FILE = 'file';
private $_cache_enabled = 'file';
private $_cache_dir = '';

/**
 * Internal function to handle requests, both authenticated and by the upload function.
 *
 * @param string $url
 * @param array $curl_opts
 * @return array
 */
private function _request($url, $curl_opts = array())
{
    // Returned cached value
    if ($this->_cache_enabled && ($response = $this->_getCached($url))) {
        return $response;
    }

    // Merge the options (custom options take precedence).
    $curl_opts = $this->_curl_opts + $curl_opts + $this->CURL_DEFAULTS;

    // Call the API.
    $curl = curl_init($url);
    curl_setopt_array($curl, $curl_opts);
    $response = curl_exec($curl);
    $curl_info = curl_getinfo($curl);

    if (isset($curl_info['http_code']) && $curl_info['http_code'] === 0) {
        $curl_error = curl_error($curl);
        $curl_error = !empty($curl_error) ? '[' . $curl_error .']' : '';

        throw new VimeoRequestException('Unable to complete request.' . $curl_error);
    }

    curl_close($curl);

    // Retrieve the info
    $header_size = $curl_info['header_size'];
    $headers = substr($response, 0, $header_size);
    $body = substr($response, $header_size);

    $final_response = array(
        'body' => $body,
        'status' => $curl_info['http_code'],
        'headers' => self::parse_headers($headers)
    );

    if ($this->_cache_enabled) {
        $this->_cache($url, $final_response);
    }

    // Return it raw.
    return $final_response;
}


/**
 * Cache a response.
 *
 * @param string $url The parameters for the response.
 * @param string $response The serialized response data.
 */
private function _cache($url, $response)
{
    $hash = md5(serialize($url));
    $response = json_encode($response);

    if ($this->_cache_enabled == self::CACHE_FILE) {
            $file = $this->_cache_dir.'/'.$hash.'.cache';
        if (file_exists($file)) {
            unlink($file);
        }
        return file_put_contents($file, $response);
    }
}

/**
 * Get the unserialized contents of the cached request.
 *
 * @param array $url The full list of api parameters for the request.
 */
private function _getCached($url)
{
    $hash = md5(serialize($url));
    $expire =  86400;

    if ($this->_cache_enabled == self::CACHE_FILE) {
        $file = $this->_cache_dir.'/'.$hash.'.cache';

        if (file_exists($file)) {
            $last_modified = filemtime($file);
            if (substr($file, -6) == '.cache' && ($last_modified + $expire) < time()) {
                unlink($file);
            }
          }

        if (file_exists($file)) {
            return json_decode(file_get_contents($file), true);
        }

    }
}

...上面的子查询中的结果集保存在名为 MyDomainRoles 的CTE中。然后你可以参考 MyDomainRoles 作为一个表。使阅读更简单,更清晰。

由于这个CTE非常简单,你可以轻松地重新编写它,但它看起来并不整洁:

WITH MyDomainRoles AS (

  --- sub-query Start
  SELECT RM.Domain, RM.RoleID
    FROM stbl_System_RolesMembersDomains AS RM WITH (NOLOCK)
    WHERE RM.Domain = (SELECT CurrentDomain FROM stbl_System_Users WITH (NOLOCK) WHERE Login = SUSER_SNAME())
      AND RM.Login = SUSER_SNAME()
  --- sub-query End

)