1

この SQL を小さくする方法はありますか?

CASE
                    WHEN @contentType = 'PrimaryBannerItem' THEN
                        [dbo].[DeathStar_GetContentLink]         (@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, ''))

                    ELSE

                        [dbo].[DeathStar_GetContentImagePath](ISNULL(a.mimetype, ''), ISNULL(c.image, ''), ISNULL(l.filename, ''))
                END AS [Image],

                CASE
                    WHEN @contentType = 'PrimaryBannerItem' THEN
                         dbo.DeathStar_GetMetadataValue(c.content_id, @urlMetadataId)


                    ELSE

                        [dbo].[DeathStar_GetContentLink](@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, ''))
                END AS Link,

もっと似せるには

CASE
    WHEN @contentType = 'PrimaryBannerItem' THEN
        [dbo].[DeathStar_GetContentLink](@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, '')) as [Image]
        dbo.DeathStar_GetMetadataValue(c.content_id, @urlMetadataId) as [Link]
    ELSE
        [dbo].[DeathStar_GetContentImagePath](ISNULL(a.mimetype, ''), ISNULL(c.image, ''), ISNULL(l.filename, '')) as [Image]
        [dbo].[DeathStar_GetContentLink](@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, '')) as [Link]
END

ご覧のとおり、コードが少し読みやすくなり、使用される行数が削減され、冗長性が回避されるためです。

4

5 に答える 5

1

両方の場合に返される結果セットが同一である場合、おそらく少しトリックをすることができます:

-- This query will return data only when @contentId = 'PrimaryBannerItem'
SELECT
  [dbo].[DeathStar_GetContentLink](@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, '')) as [Image]
  ,dbo.DeathStar_GetMetadataValue(c.content_id, @urlMetadataId) as [Link]
  ,OtherFields
FROM
  YourTables
WHERE
  (@contentId = 'PrimaryBannerItem')
  -- Other WHERE clauses here

UNION ALL

-- This query will return data only when @contentId <> 'PrimaryBannerItem'
SELECT
  [dbo].[DeathStar_GetContentImagePath](ISNULL(a.mimetype, ''), ISNULL(c.image, ''), ISNULL(l.filename, '')) as [Image]
  ,[dbo].[DeathStar_GetContentLink](@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, '')) as [Link]
  ,OtherFields
FROM
  YourTables
WHERE
  (@contentId <> 'PrimaryBannerItem')
  -- Other WHERE clauses

このように、IF、CASEなどを使用する必要はありません。

:他のパラメーターの組み合わせに依存する値など、より複雑な条件が発生し始めた場合、パフォーマンスと、さらに重要なことに、メンテナンスの両方の観点から、これは最も効率的なアプローチではない可能性があります。

于 2012-07-29T13:50:10.570 に答える
0

おそらくそうではありません。

2番目のコードブロックで提案している方法は機能しません。CASEはステートメントであり、単一の列の値を返すためにのみ使用できます。そのため、の結果をCASE列として定義しますが、caseステートメントで列を定義することはできません。これがそれを説明するSOです。

私が考えることができる唯一の可能性は、ストアドプロシージャ/関数を更新してnull値を許可することです。これにより、すべてのを取り除くことができますISNULL。これは、ストアドプロシージャについてこれを説明するリンクです。

于 2012-07-27T15:01:05.640 に答える
0

いいえ。CASE式はスカラー、単一の値を返します。2つの値を返すことはできません。2列の値を返すことはできません。

于 2012-07-27T21:34:32.863 に答える
0

この解決策は可能ですか?

-- First case
IF @contentType = 'PrimaryBannerItem' BEGIN
    SELECT [dbo].[DeathStar_GetContentLink](@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, '')) as [Image],
    dbo.DeathStar_GetMetadataValue(c.content_id, @urlMetadataId) as [Link]

-- Second case
END ELSE BEGIN
    SELECT [dbo].[DeathStar_GetContentImagePath](ISNULL(a.mimetype, ''), ISNULL(c.image, ''), ISNULL(l.filename, '')) as [Image],
    [dbo].[DeathStar_GetContentLink](@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, '')) as [Link]
END

選択しているフィールドがこれらだけである場合は、確かにきれいに見えます。しかし、私はあなたのコード全体を見ていないと確信しているので、これはあなたが望むものを正確に与えないかもしれません.

于 2012-07-27T17:33:26.387 に答える
0

CASE ... WHEN ... ELSE ...これが良いかどうかはわかりませんが、例のように、クエリ全体を繰り返すか、すべての列に繰り返し式を使用する必要がなければ、おそらく他のオプションはありません。

SELECT
  …
  COALESCE(choice1.Image, choice2.Image) AS Image,
  COALESCE(choice1.Link , choice2.Link ) AS Link,
  …
FROM
  …
OUTER APPLY (
  SELECT
    [dbo].[DeathStar_GetContentLink](@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, '')) as [Image],
    dbo.DeathStar_GetMetadataValue(c.content_id, @urlMetadataId) as [Link]
  WHERE @contentType = 'PrimaryBannerItem'
) AS choice1
OUTER APPLY (
  SELECT
    [dbo].[DeathStar_GetContentImagePath](ISNULL(a.mimetype, ''), ISNULL(c.image, ''), ISNULL(l.filename, '')) as [Image],
    [dbo].[DeathStar_GetContentLink](@contentId, c.content_id, @pageCollectionId, ISNULL(l.filename, '')) as [Link]
  WHERE @contentType <> 'PrimaryBannerItem'
    /* or, perhaps, "WHERE @contentType = 'something else'" */
) AS choice2
WHERE
  …

2 つの OUTER APPLY のうち、行を返すことができるのは一方だけで、もう一方は常に空の行セットを返し、その列はそれに応じて NULL と評価されます。つまり、COALESCE を使用して「正しい」結果を返すことができます。対応する列を必要な順序で指定するだけで、NULL 以外の最初の列が返されます。

于 2012-07-27T17:29:22.737 に答える