0

ColdFusion 10 で作成しているこのレポートをどのように書くのが最善かを検討しています。

基本的には、MSSQL データベースの 2 つのテーブルからデータを読み取り、特定の列で見つかった内容に基づいていくつかの条件を適用し、データを Excel に入力して電子メールで送信することで構成されます。テーブルからデータを読み取り、POIUTILITY を使用してスプレッドシートを作成し、電子メールで送信するのと同じくらい簡単なレポートを以前に作成しましたが、これは条件のために少し異なります。poiutility の代わりに cfspreadsheet を使用することについて読んだことがありますが、この場合はよくわかりません。

これは、テーブルのレイアウトがどのように見えるかの例です。

Table1
ID | Name | Address

Table2 
ID | AppsInfo

Excel レポートには、次のようなデータが配置された 1 つのシートがあります。

ID    | Name  | Address | AppAlpha | AppBravo | AppDelta | 
12345 | John  | 123 Ave | Yes      | Yes      | No       | 

私の問題は、table2 の AppsInfo 列に各 ID の xml 形式が含まれていることです。

<start>
<id=”12345”&gt;
<AppName=”AppDelta”&gt;
<AppName=”AppBravo”
</id>
</start>

私のExcelシートの各行では、データは、特定のIDのappsinfo列にアプリが含まれている場合は対応する行にyesとしてリストされ、そのアプリが含まれていない場合はNo.

上記のレイアウトの例から、Excel の最終的な形式は次のように表示されます。

ID    | Name  | Address | AppAlpha | AppBravo | AppDelta |
12345 | John  | 123 Ave | No       | Yes      | Yes      |

などなど、IDごとに…。

table2 の appsinfo 列に特定のアプリが含まれている場合は「はい」と書き込み、含まれていない場合は対応する行の各 ID に「いいえ」と書き込みます。

4

3 に答える 3

2

Leigh は答えに私を打ち負かしましたが、SQL の XML 機能を使用した同様のソリューションがありました。XML を扱うのは面倒ですが、SQL Server には XML を扱うための構文があります。

SELECT t1.ID
    , t1.Name
    , t1.Address
    --, t2.AppsInfo
    , CASE WHEN t2.AppsInfo.exist('//start/id/AppName[@value="AppAlpha"]') = 1 THEN 'Yes' ELSE 'No' END AS AppAlpha
    , CASE WHEN t2.AppsInfo.exist('//start/id/AppName[@value="AppBravo"]') = 1 THEN 'Yes' ELSE 'No' END AS AppBravo
    , CASE WHEN t2.AppsInfo.exist('//start/id/AppName[@value="AppDelta"]') = 1 THEN 'Yes' ELSE 'No' END AS AppDelta
FROM #table1 t1
INNER JOIN #table2 t2 ON t1.ID = t2.ID

私のセットアップは次のとおりです。

Create TABLE #table1 ( ID int, Name varchar(100), Address varchar(200) )
Create TABLE #table2 ( ID int, AppsInfo xml )

INSERT INTO #table1 (ID, Name, Address)
SELECT 1, 'John', '123 Sesame St'
UNION ALL
SELECT 2, 'Jim', '42 Douglas Ln'
UNION ALL
SELECT 3, 'Jack', '1 Elm St'
UNION ALL
SELECT 4, 'Joe', '21 Jump St'

INSERT INTO #table2 (ID, AppsInfo)
SELECT 1, '<start><id value="1"><AppName value="AppDelta"/><AppName value="AppBravo"/></id></start>'
UNION ALL
SELECT 2, '<start><id value="2"><AppName value="AppAlpha"/><AppName value="AppDelta"/><AppName value="AppBravo"/></id></start>'
UNION ALL 
SELECT 3, '<start><id value="3"><AppName value="AppBravo"/></id></start>'
UNION ALL 
SELECT 4, '<start><id value="4"><AppName/></id></start>'

また、有効にするために XML を少し変更する必要がありました。私のソリューションと Leigh のソリューションの唯一の本当の違いは、Excel ではなく、SQL CASE を使用して Yes/No を出力していることです。どちらの方法でも同様に機能します。

ただし、使用している実際の XML の構造は、これらのクエリに影響を与える可能性があります。ここにサンプルブロックを置いてもらえますか? また、使用している SQL Server のバージョンは何ですか? SQL 2000 の XML 構文は SQL 2005+ とは少し異なり、SQL 2000 には XML データ型がありません。

クエリからスプレッドシートを作成するには、Ray Camden の優れた記事があります。また、 cfspreadsheet のAdob​​eドキュメントもあります。

于 2013-08-01T15:21:20.660 に答える
1

アプリケーション列が 3 つしかない場合、SQL Server の xml 関数を使用して結果を sql で生成する別のオプションがあります。bit3 つの列のそれぞれに値を返すだけです。(注: 投稿の xml サンプルを微調整して有効にしましたが、SQLFiddleは一般的な考え方を示しています。)

SELECT t1.ID
        , t1.Name
        , t1.Address
        , t2.appsInfo.exist('//start/id/App[@Name="AppAlpha"]') AS AppAlpha
        , t2.appsInfo.exist('//start/id/App[@Name="AppBravo"]') AS AppBravo
        , t2.appsInfo.exist('//start/id/App[@Name="AppDelta"]') AS AppDelta
FROM @table1 t1 INNER JOIN @table2 t2 ON t2.ID = t1.ID

次に、スプ​​レッドシートでカスタム セル形式を列に適用して、0/1 の代わりに yes/no を表示します。CF の組み込みスプレッドシート機能を使用していると仮定すると、形式は次のようになります。

         {dataformat='"Yes";"Yes";"No"'}
于 2013-08-01T03:59:22.747 に答える
0

最も簡単で汚い方法は、文字列の検出によるものだと思います。

<cfquery name="AppData" datasource="MyDSN">
SELECT
    t1.id, t1.name, t1.address, t2.appinfo
FROM
    table1 t1
    INNER JOIN table2 t2 ON t1.id = t2.id
</cfquery>

<cfscript>
// Return a Yes/No for App's Existence in a string
function checkApp( app, string) {
  return findNoCase( app, string ) ? 'NO' : 'YES';
}
</cfscript>

<cfoutput query="AppData">
#id# #name# #address# #checkApp( 'AppDelta', appinfo )# #checkApp( 'AppBravo', appinfo )#
</cfoutput>
于 2013-07-31T20:00:04.927 に答える