使用 PHP 计算 Oracle 中所选行的数量

发布于 2024-10-06 22:43:37 字数 2847 浏览 1 评论 0原文

我正在为大学做这个项目,它基本上是一个电影数据库,对于几个查询,我需要知道选择了多少行。目前,有两种情况我需要这样做:

  • 显示单个电影信息。我希望通过所选行的计数来了解数据库是否包含用户选择的电影。 或者有更好的解决方案吗?
  • 所选电影有流派,我需要知道有多少种流派,以便我可以构造一个流派用 | 分隔的字符串,而无需添加1 到字符串的末尾。

对于 MySQL,这很简单,我只需查询数据库并使用 mysql_num_rows() ,但 oci_num_rows() 对于 SELECT 语句的工作方式并不完全相同。

我发现 OCI/PHP 的唯一解决方案是:

if(is_numeric($mid) && $mid > 0) {
        $stid = oci_parse($db,
            'SELECT COUNT(*) AS NUM_ROWS
            FROM movies
            WHERE mid = '.$mid
        );

        oci_define_by_name($stid, 'NUM_ROWS', $num_rows);
        oci_execute($stid);
        oci_fetch($stid);

        if($num_rows > 0) {
            $stid = oci_parse($db,
                'SELECT title, year, synopsis, poster_url
                FROM movies
                WHERE mid = '.$mid
            );

            oci_execute($stid);

            $info = oci_fetch_assoc($stid);

            $stid = oci_parse($db,
                'SELECT COUNT(*) AS NUM_ROWS
                FROM genres g, movies_genres mg
                WHERE mg.mid = '.$mid.' AND g.gid = mg.gid'
            );

            oci_define_by_name($stid, 'NUM_ROWS', $num_rows);
            oci_execute($stid);
            oci_fetch($stid);

            $stid = oci_parse($db,
                'SELECT g.name AS genre
                FROM genres g, movies_genres mg
                WHERE mg.mid = '.$mid.' AND g.gid = mg.gid');

            oci_execute($stid);

            $genres_list = null;

            while($row = oci_fetch_assoc($stid)) {
                $genres_list .= $row['GENRE'];

                if($num_rows > 1) {
                    $genres_list .= ' | ';
                    $num_rows--;
                }
            }

            $Template->assignReferences(array(
                'Index:LinkURI'    => $link_uri,
                'Movie:Title'      => $info['TITLE'],
                'Movie:Year'       => $info['YEAR'],
                'Movie:GenresList' => $genres_list,
                'Movie:Synopsis'   => $info['SYNOPSIS'],
                'Movie:PosterURL'  => $info['POSTER_URL'] // FIX: Handle empty poster link
            ));

            $Template->renderTemplate('movieinfo');
        } else {
            // TODO: How to handle this error?
        }
    } else {
        // TODO: How to handle this error?
    }

但我不喜欢它。我总是需要进行 2 个查询来计算行数,然后选择实际数据,并且有太多代码行只是为了计算行数。

此代码没有显示它(尚未完成,因为我正在寻找更好的解决方案),但我还需要为电影导演/编剧做同样的事情。

是否有更好且更简单的解决方案来完成此任务,或者这是唯一的方法?

我可以在获取循环中添加分隔符,直到完成,然后使用 PHP 函数修剪字符串中的最后一个分隔符,但对于这个项目,我被迫使用序列、视图、函数、过程和触发器。这些有助于解决我的问题吗?

我知道序列是什么,我已经在使用它们了,但我不知道它们有什么帮助。

对于视图,他们可能不会那么简化代码(它基本上是一个存储查询,对吗?)。对于功能、程序和触发器,据我了解,我也不明白它们有什么帮助。

解决方案?

I'm doing this project for university, which is basically a movie database and for a couple of queries I need to know how many rows were selected. For now, there's 2 situations where I need this:

  • Display a single movie information. I want the count of selected rows to know if the database contains the selected movie by the user. Or is there a better solution for this?
  • That selected movie has genres, I need to know how many so that I can construct a string with the genres separated by | without adding one to the end of the string.

With MySQL this is easy, I just query the database and use mysql_num_rows() but oci_num_rows() doesn't work quite the same for the SELECT statement.

The only solution I found with OCI/PHP is this:

if(is_numeric($mid) && $mid > 0) {
        $stid = oci_parse($db,
            'SELECT COUNT(*) AS NUM_ROWS
            FROM movies
            WHERE mid = '.$mid
        );

        oci_define_by_name($stid, 'NUM_ROWS', $num_rows);
        oci_execute($stid);
        oci_fetch($stid);

        if($num_rows > 0) {
            $stid = oci_parse($db,
                'SELECT title, year, synopsis, poster_url
                FROM movies
                WHERE mid = '.$mid
            );

            oci_execute($stid);

            $info = oci_fetch_assoc($stid);

            $stid = oci_parse($db,
                'SELECT COUNT(*) AS NUM_ROWS
                FROM genres g, movies_genres mg
                WHERE mg.mid = '.$mid.' AND g.gid = mg.gid'
            );

            oci_define_by_name($stid, 'NUM_ROWS', $num_rows);
            oci_execute($stid);
            oci_fetch($stid);

            $stid = oci_parse($db,
                'SELECT g.name AS genre
                FROM genres g, movies_genres mg
                WHERE mg.mid = '.$mid.' AND g.gid = mg.gid');

            oci_execute($stid);

            $genres_list = null;

            while($row = oci_fetch_assoc($stid)) {
                $genres_list .= $row['GENRE'];

                if($num_rows > 1) {
                    $genres_list .= ' | ';
                    $num_rows--;
                }
            }

            $Template->assignReferences(array(
                'Index:LinkURI'    => $link_uri,
                'Movie:Title'      => $info['TITLE'],
                'Movie:Year'       => $info['YEAR'],
                'Movie:GenresList' => $genres_list,
                'Movie:Synopsis'   => $info['SYNOPSIS'],
                'Movie:PosterURL'  => $info['POSTER_URL'] // FIX: Handle empty poster link
            ));

            $Template->renderTemplate('movieinfo');
        } else {
            // TODO: How to handle this error?
        }
    } else {
        // TODO: How to handle this error?
    }

But I don't like it. I always need to make 2 queries to count the rows and then select the actual data and there's too many lines of code just to count the rows.

This code doesn't show it (haven't done it yet cause I'm looking for a better solution) but I'll also need to do the same for the movie directors/writers.

Is there any better and simpler solution to accomplish this or this is the only way?

I could add separators in the fetch loop until it finishes and then use PHP functions to trim the last separator from the string, but for this project I'm forced to use SEQUENCES, VIEWS, FUNCTIONS, PROCEDURES and TRIGGERS. Do any of these help solving my problem?

I know what SEQUENCES are, I'm using them already but I don't see how can they help.

For VIEWS, they probably wouldn't simplify the code that much (it's basically a stored query right?). For FUNCTIONS, PROCEDURES and TRIGGERS, as far as I understand them, I can't see how can they be of any help either.

Solutions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

被翻牌 2024-10-13 22:43:37

为什么初始计数呢?只需发布您对电影标题的选择即可。如果没有找到,请进行错误处理。如果是,请继续!如果您确实需要计数,请使用分析将计数添加到您的查询中:

'SELECT title, year, synopsis, poster_url
      , COUNT(*) OVER (PARTITION BY mid) mcount
   FROM movies
  WHERE mid = '.$mid

这同样适用于您的流派选择。

编辑:

关于分析函数链接。我发现从 Oracle 文档中获取分析有点困难。 Shouvik Basu 的分析函数示例 提供了一些关于如何使用它们的简单指导,对我很有帮助一点。

Why do the initial count at all? Just issue your select for the movie title. If it's not found, do your error processing. If it is, continue on! If you really need the count, use an analytic to add the count to your query:

'SELECT title, year, synopsis, poster_url
      , COUNT(*) OVER (PARTITION BY mid) mcount
   FROM movies
  WHERE mid = '.$mid

The same goes for your genre selection.

EDIT:

Oracle documentation on Analytic Functions link. I found that analytics are a bit difficult to get from the Oracle docs. Analytic functions by Example by Shouvik Basu provides some simple guidance as to how to use them and helped me quite a bit.

背叛残局 2024-10-13 22:43:37

你可以试试这个

$conn = oci_pconnect('user', 'password', 'connectionstring');
$resource = oci_parse($conn, $sql);
oci_execute($resource, OCI_DEFAULT);

$results=array();
$numrows = oci_fetch_all($resource, $results, null, null, OCI_FETCHSTATEMENT_BY_ROW);

干杯

You can try this

$conn = oci_pconnect('user', 'password', 'connectionstring');
$resource = oci_parse($conn, $sql);
oci_execute($resource, OCI_DEFAULT);

$results=array();
$numrows = oci_fetch_all($resource, $results, null, null, OCI_FETCHSTATEMENT_BY_ROW);

Cheers

一指流沙 2024-10-13 22:43:37

您可以使用 ocirowcount 它在进行选择时的行为应该与 mysql_num_rows 类似

you can use the ocirowcount it should behave just like mysql_num_rows when making a select

萌辣 2024-10-13 22:43:37

oci_num_rows() 如果在 oci_fetch_array() 之后执行,将为您提供总行数

oci_num_rows() Will give you the total row count if executed AFTER oci_fetch_array()

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文