Используя PHP/PDO/MySQL возможно использовать подстановочный знак для столбцов, когда выбор сделан на нескольких таблицах, и ключи возвращенного массива полностью определяются для предотвращения столкновения имени столбца?
пример:
ВЫБЕРИТЕ * из table1, table2;
дает:
Ключи массива являются 'table1.id', 'table2.id', 'table1.name' и т.д.
Я попробовал "ВЫБОР table1.*, table2.*...", но ключи возвращенного массива не были полностью определены так, столбцы с тем же именем столкнулись и были перезаписаны.
Да, можно. Самый простой способ - с помощью pdo, хотя есть по крайней мере несколько других расширений, которые на это способны.
Установите атрибут для объекта PDO , а не для PDOStatment .
$PDO->setAttribute(PDO::ATTR_FETCH_TABLE_NAMES, true);
Вот и все. Затем вы получаете ключи ассоциативного массива, такие как $ row ['myTable.myColumn']
. Это работает, если вы также получаете объект (например, через PDO :: FETCH_OBJECT
), так что будьте осторожны, потому что вам нужно получить доступ к таким свойствам, как $ obj -> {'myTable.myColumn'}
* В руководстве говорится, что атрибут PDO :: ATTR_FETCH_TABLE_NAMES
поддерживается только некоторыми драйверами. Если вышеперечисленное не работает, вместо него может работать .
$pdoStatement->setFetchMode(PDO::FETCH_NUM);
$pdoStatement->execute();
//build our associative array keys
$qualifiedColumnNames = array();
for ($i = 0; $i < $pdoStatement->columnCount(); $i++) {
$columnMeta = $pdoStatement->getColumnMeta($i);
$qualifiedColumnNames[] = "$columnMeta[table].$columnMeta[name]";
}
//fetch results and combine with keys
while ($row = $pdoStatement->fetch()) {
$qualifiedRow = array_combine($qualifiedColumnNames, $row);
print_r($qualifiedRow);
}
Такой же базовый шаблон используется для других расширений базы данных
$res = mysql_query($sql);
//build our associative array keys
$qualifiedColumnNames = array();
for ($i = 0; $i < mysql_num_fields($res); $i++) {
$columnMeta = mysql_fetch_field($res, $i);
$qualifiedColumnNames[] = "$columnMeta[table].$columnMeta[name]";
}
//fetch results and combine with keys
while ($row = mysql_fetch_row($res)) {
$qualifiedRow = array_combine($qualifiedColumnNames, $row);
print_r($qualifiedRow);
}
$res = $mysqli->query($sql);
//build our associative array keys
$qualifiedColumnNames = array();
foreach ($res->fetch_fields() as $columnMeta) {
$qualifiedColumnNames[] = "{$columnMeta->table}.{$columnMeta->name}";
}
//fetch results and combine with keys
while ($row = $res->fetch_row()) {
$qualifiedRow = array_combine($qualifiedColumnNames, $row);
print_r($qualifiedRow);
}
Это также должно работать с псевдонимами таблиц (проверено в php 7.1) - в квалифицированном имени столбца будет использоваться псевдоним таблицы.
вы можете сделать this:
SELECT Table1.*,Table2.xyz, Table2.abc,... From...
где вы получаете все столбцы из одной таблицы, используя "*", а затем только столбцы из другой таблицы, которая вам нужна, поэтому конфликтов нет.
Вы также можете использовать псевдонимы столбцов, где вы «переименовываете» столбец:
SELECT Table1.A AS T1_A,Table2.A AS T2_A,... From...
ваш результирующий набор будет состоять из столбцов T1_A и T2_A
К сожалению, нет; нет синтаксиса SQL для обеспечения уникальности имен столбцов.
Если вы действительно не знаете имена столбцов и должны использовать SELECT *
, ваш единственный реальный вариант - вернуться к очень уродливому динамическому SQL, который мог бы проверять структуру таблиц. и сгенерируйте запрос, который выбрал бы их все явно с префиксом имени таблицы.
Я не знаю, какую СУБД вы используете, но что-то вроде этого должно работать на SQL Server:
declare @columns table (idx int identity(1,1), tablename varchar(100), columnname varchar(100))
insert into @columns (tablename, columnname)
select tablename, columnname
from INFORMATION_SCHEMA.COLUMNS
where tablename in ('table_1', 'table_2')
declare @sql nvarchar(4000)
declare @i int
declare @cnt in
declare @col varchar(100)
declare @table varchar(100)
select @i = 0, @cnt = max(idx), @sql = '' from @columns
while @i < @cnt
begin
select @i = @i + 1
select @col = columnname, @table = tablename from @columns where idx = @i
if len(@sql) > 0
select @sql = @sql + ', '
select @sql = @sql + '[' + @table + '].[' + @col + '] as [' + @table + '_' + @col + ']'
end
select @sql = 'select ' + @sql + ' from table_1, table_2'
exec sp_executesql @sql
К сожалению, PHP (особенно расширения MySQL, PgSQL, MSSQL) всегда будет перезаписывать ваши столбцы в случае перекрытия.
Я бы порекомендовал создать представление
в вашей базе данных и задать псевдоним для ваших столбцов, чтобы они были «полностью определенными».
Например: (MySQL)
CREATE VIEW viewTable1Table2 AS
SELECT
t1.field1 AS Table1Field1
t2.field1 AS Table2Field1
FROM Table1 t1
INNER JOIN Table2 t2
ON t1.id = t2.id;
Синтаксис может быть несовершенным, но вы можете получить общее представление о том, о чем я говорю.