J-Pro
Новичок
EXECUTE и CONCAT внутри хранимой процедуры мешает нормальному fetch-у.
Ребятушки, проблема возникла
Значит, для удобства и сокращения написанного, я решил делать выборку из таблиц в хранимых процедурах по различным критериям в одной хранимой процедуре. Выглядит это так:
Раньше же, если писать просто, вот так:
, необходимо было писать условия и несколько раз копипэйстить блок SELECT с разным условием WHEN.
Вызываю я эти процедуры из пхп.
НО, проблема: Первый случай перестал fetch-иться нормально, показывает, что в резалте только названия столбцов, а один раз вообще перемешал как-то все строки, КРОМЕ, опять же, названий столбцов. Т.е. названия одинаковые: ID, Name, а данные в них перемешаны из разных столбцов.
НИЧЕГО НЕ МЕНЯЯ в алгоритме вывода данных из резалтсета, т.е. вообще не прикасаясь к коду php, а просто заменяя хранимую процедуру в первом примере на хранимую процедуру во втором(без EXECUTE), всё работает превосходно, все данные возвращаются.
Хочу отметить, что в консоли, простым CALL оба варианта выше дают одинаковые результаты. Так почему же эти результаты не попадают в stmt?
Кто-то сталкивался с такой проблемой?
Спасибо заранее за ответ.
-~{}~ 02.11.06 15:29:
Народ, помогайте, ищу в нете нигде нет ничего подобного...
Уж не знаю что и делать... Почему так происходит - не пойму... вроде, в SQL-редакторе результаты одинаковые, а тут...
Может, после EXECUTE надо что-то ещё сделать, чтобы всё ок было в пхп?
Код пхп на всякий случай:
В итоге получаю $retArr, матрицу, первой строкой которой являются имена столбцов, остальными - данные вернувшейся таблицы.
Но, вот, оставляя код таким же и меняя только процедуру - получаю ошибку... странно...
Жду помощи...
-~{}~ 03.11.06 17:13:
Ребят, неужели никто не встречался с подобными вещами?
Может, кто-то поможет?
-~{}~ 06.11.06 13:48:
Жаль, но мне кажется, ответа на мой вопрос никто не знает...
Странно... в PostgreSQL этот вопрос не возникал, а тут...
Ребятушки, проблема возникла

Значит, для удобства и сокращения написанного, я решил делать выборку из таблиц в хранимых процедурах по различным критериям в одной хранимой процедуре. Выглядит это так:
PHP:
CREATE PROCEDURE `GetAllDiscounts`(IN activitytypeid BIGINT, IN languageid BIGINT)
NOT DETERMINISTIC
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE statement VARCHAR(1024);
DECLARE lang VARCHAR(500);
DECLARE activitytype VARCHAR(500);
IF (activitytypeid IS NULL) THEN SET activitytype := ' AND 1=1';
ELSE SET activitytype := CONCAT(' AND AT.`ActivityTypeID` = ', activitytypeid);
END IF;
IF (languageid IS NULL) THEN SET lang := ' AND 1=1';
ELSE SET lang := CONCAT(' AND D.`LanguageID` = ', languageid);
END IF;
SET @statement :=
CONCAT('SELECT D.`DiscountID`,
D.`ActivityTypeID`,
AT.Name,
AT.Description,
D.`ArticleName`,
D.`PathToPhoto`,
D.`PathToFirstPhoto`,
D.`Value`,
D.`OldPrice`,
D.`NewPrice`,
D.`StartDate`,
D.`EndDate`,
D.`Description`,
D.`RegisteredOn`,
D.`UpdatedBy`,
D.`UpdatedOn`,
D.`LanguageID`,
L.Name AS LanguageName,
L.Initials AS LanguageInitials
FROM Discounts D
JOIN ActivityTypes AT ON D.`ActivityTypeID` = AT.`ActivityTypeID`
JOIN Languages L ON D.LanguageID = L.LanguageID
WHERE 1 = 1 ', lang, activitytype);
PREPARE stmt FROM @statement;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END;
Раньше же, если писать просто, вот так:
PHP:
CREATE PROCEDURE `GetAllDiscounts`(IN activitytypeid BIGINT, IN languageid BIGINT)
NOT DETERMINISTIC
SQL SECURITY DEFINER
COMMENT ''
BEGIN
SELECT D.`DiscountID`,
D.`ActivityTypeID`,
AT.Name,
AT.Description,
D.`ArticleName`,
D.`PathToPhoto`,
D.`PathToFirstPhoto`,
D.`Value`,
D.`OldPrice`,
D.`NewPrice`,
D.`StartDate`,
D.`EndDate`,
D.`Description`,
D.`RegisteredOn`,
D.`UpdatedBy`,
D.`UpdatedOn`,
D.`LanguageID`,
L.Name AS LanguageName,
L.Initials AS LanguageInitials
FROM Discounts D
JOIN ActivityTypes AT ON D.`ActivityTypeID` = AT.`ActivityTypeID`
JOIN Languages L ON D.LanguageID = L.LanguageID
LEFT OUTER JOIN DiscountsTradeCenters DTC ON D.`DiscountID` = DTC.`DiscountID`
LEFT OUTER JOIN `tradecenters` TC ON DTC.`TradeCenterID` = TC.`TradeCenterID`;
END;
Вызываю я эти процедуры из пхп.
НО, проблема: Первый случай перестал fetch-иться нормально, показывает, что в резалте только названия столбцов, а один раз вообще перемешал как-то все строки, КРОМЕ, опять же, названий столбцов. Т.е. названия одинаковые: ID, Name, а данные в них перемешаны из разных столбцов.
НИЧЕГО НЕ МЕНЯЯ в алгоритме вывода данных из резалтсета, т.е. вообще не прикасаясь к коду php, а просто заменяя хранимую процедуру в первом примере на хранимую процедуру во втором(без EXECUTE), всё работает превосходно, все данные возвращаются.
Хочу отметить, что в консоли, простым CALL оба варианта выше дают одинаковые результаты. Так почему же эти результаты не попадают в stmt?
Кто-то сталкивался с такой проблемой?
Спасибо заранее за ответ.
-~{}~ 02.11.06 15:29:
Народ, помогайте, ищу в нете нигде нет ничего подобного...
Уж не знаю что и делать... Почему так происходит - не пойму... вроде, в SQL-редакторе результаты одинаковые, а тут...
Может, после EXECUTE надо что-то ещё сделать, чтобы всё ок было в пхп?
Код пхп на всякий случай:
PHP:
$procedureCallStatement = "CALL GetAllDiscounts(?, ?)";
$stmt = $mysqli->prepare($procedureCallStatement);
$stmt->bind_param('ii', $activityTypeID, $languageID);
$res = $stmt->execute();
if($res)
{
$meta = $stmt->result_metadata();
if(!$meta) return false;
$retArr = array(array(), array());
$colNames = array();
$tmpArray = array();
while ($field = $meta->fetch_field())
{ // получаем массив названий столбцов
$names[] = $field->name;
$colNames[] = $field->name;
}
$retArr[0] = $colNames; // первая строка двумерного массива
// теперь нашими утилитами получаем ассоциативныЕ массивЫ резалт сета
$j = 1;
while($assocArr = mps_fetch_assoc($stmt))
{
$namesQuan = count($names);
for($i = 0; $i < $namesQuan; $i++)
{
$tmpArray[$i] = $assocArr[$names[$i]];
}
$retArr[$j] = $tmpArray;
$j++;
}
}
// #######################################################################################################
public function mps_fetch_assoc(&$stmt)
{ // Ф-ция для того, чтобы резалт превратить в ассоциативный массив: столбец-данные
$meta = $stmt->result_metadata();
$retval[] = &$stmt;
$tmp;
$names;
while ($field = $meta->fetch_field())
{ // получаем массив названий столбцов
$names[] = $field->name;
}
$tmp = $names;
for ($c = 0; $c < count($names); $c++)
{ // копируем полученные названия столбцов в другой массив ("Id", "Name", .....)
$retval[] = &$tmp[$c];
}
// Биндим значения столбцов, передавая массив НАЗВАНИЙ ПЕРЕМЕННЫХ, составленный из
// массива названий столбцов. Т.к. надо: $stmt->bind_result($col1, $col2, $col3, и т.д....);
call_user_func_array("mysqli_stmt_bind_result", $retval);
// Если всё прошло успешно, данные получаются фетчем, скидываем их в ассоциативный массив
if ($stmt->fetch())
{
$assoc_array;
for ($c = 0; $c < count($names); $c++)
{
$assoc_array[$names[$c]] = $retval[$c + 1];
}
return $assoc_array;
}
else
{
return FALSE;
}
}
Но, вот, оставляя код таким же и меняя только процедуру - получаю ошибку... странно...
Жду помощи...
-~{}~ 03.11.06 17:13:
Ребят, неужели никто не встречался с подобными вещами?
Может, кто-то поможет?

-~{}~ 06.11.06 13:48:
Жаль, но мне кажется, ответа на мой вопрос никто не знает...
Странно... в PostgreSQL этот вопрос не возникал, а тут...
