Вложенные запросы в CF
-
14-09-2020 - |
Вопрос
Я использую этот код для отображения списка платформ.Если при входе на страницу был указан PlatformID, я хотел бы создать список жанров под указанной платформой.
- доступ к browse.cfm был осуществлен по ссылке, в которой был указан PlatformID, равный 1
- browse.cfm выведет список всех доступных платформ
browse.cfm теперь будет отображать список всех доступных жанров под PlatformID, равным 1.
<ul> <li>Browse</li> <cfoutput query="qGetPlatforms"> <li> <a href="browse.cfm?platformID=#URLEncodedFormat(Trim(qGetPlatforms.platformID))#">#qGetPlatforms.pName#</a> <cfif URL.platformID EQ qGetPlatforms.platformID> <ul> <cfoutput query="qGetGenres"> <li><a href="browse.cfm?genreID=#URLEncodedFormat(Trim(qGetGenres.genreID))#">#qGetGenres.gName#</a></li> </cfoutput> </ul> </cfif> </li> </cfoutput> </ul>
Однако, используя этот подход, я получаю недопустимую конфигурацию вложенности.Как мне это исправить?Или есть другой подход для достижения той же идеи?
Спасибо
МОИ запросы:
<!---Get platforms--->
<cffunction
name="fGetPlatforms"
access="public"
returntype="query"
output="false"
hint="I get all the platforms">
<!---Local var--->
<cfset qGetPlatforms = "">
<!---Database query--->
<cfquery name="qGetPlatforms" datasource="#REQUEST.datasource#">
SELECT
platforms.platformID,
platforms.platformName AS pName
FROM
platforms
</cfquery>
<cfreturn qGetPlatforms>
</cffunction>
<!---Get genres--->
<cffunction
name="fGetGenres"
access="public"
returntype="query"
output="false"
hint="I get all the genres">
<!---Local var--->
<cfset qGetGenres = "">
<!---Database query--->
<cfquery name="qGetGenres" datasource="#REQUEST.datasource#">
SELECT
genres.genreID,
genres.genreName AS gName
FROM
genres
</cfquery>
<cfreturn qGetGenres>
</cffunction>
Решение
Вы можете использовать <cfloop query="qGetGenres"></cfloop>
, они могут быть вложенными.
ИМО, использование cfoutput для зацикливания запросов - это старый стиль, и его следует избегать.Используйте cfoutput для вывода, cfloop для зацикливания, и у вас будет более читаемый код.
Другие советы
more food for thought is to use an inner join between the two tables, combine and retrieve everything in one query and then use cfoutput's group attribute to display the results:
<cfset URL.platformID = int(val(URL.platformID))>
<cfquery name="getPlatformsAndGenres" datasource="#REQUEST.datasource#">
SELECT
p.platformID AS platformID
,p.platformName AS pName
,g.genreID AS genreID
,g.genreName AS gName
FROM
platforms p
INNER JOIN genres g
ON p.platformID = g.platformID
WHERE
p.platformID = <cfqueryparam cfsqltype="cf_sql_integer" value="#URL.platformID#">
ORDER BY
pName
,genreName
</cfquery>
Once you have everything in one query, you can use <cfoutput query="getPlatformsAndGenres" group="pName">
to lessen your code:
<ul>
<li>Browse</li>
<cfoutput query="getPlatformsAndGenres" group="pName">
<li>
<a href="browse.cfm?platformID=#URLEncodedFormat(Trim(platformID))#">#pName#</a>
<ul>
<cfoutput>
<li><a href="browse.cfm?genreID=#URLEncodedFormat(Trim(genreID))#">#gName#</a></li>
</cfoutput>
</ul>
</cfif>
</li>
</cfoutput>
</ul>