Índice 1.Ficha técnica....................................................................................................................5 Conte1to da actividade&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&2 ,tulo da actividade&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&2 +esultados de aprendi*a1e do curr,culo&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&2 4b1ectivos didácticos e t,tulo e descrición da actividade&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&2 Criterios de avaliación&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Contidos&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& $ctividades de ensino e aprendi*a1e e de avaliación5 m)todos5 recursos e instrumentos de avaliación &&&&&&&&&&&&&&&&& &&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&6 &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&6
2.A1. Acceso a base de datos MySQL..............................................................................8 1.1Introdución 1.1Introdu ción................ ................................. .................................. .................................. .................................. .................................. .................................. ....................8 ...8 1.2Actividade...........................................................................................................................8 $cceso a base de datos&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&7 $PIs de P8P para acceder ás bases de datos de M9S:' &&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&7 &&&&&&&&&&&&&&&&&&&&&&&&&&7
Tarefas...... Tare fas....................... .................................. .................................. .................................. .................................. .................................. ............................ ................ .......... ......19 .19 !&<&!arefa !& Creación e cone1ión a base de datos de traballo&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&<0 $utoavaliación&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&<0 !&<&<arefa <& +eali*ación de consultas de acción&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&<< $utoavaliación&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&<3 !&<&3arefa 3& +eali*ación de consultas de selección&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&<= $utoavaliación&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&<= !&<&=arefa =& +eali*ación de operacións .ue implican transaccións&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&<6 $utoavaliación&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&<6 !&<&2arefa 2& +eali*ación de operacións con consultas preparadas&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&<7 $utoavaliación&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&<7 1.3Textos de apoio ou de referencia.....................................................................................30 1.4Recursos didácticos.........................................................................................................30
3.Avaliació 3.Av aliación....... n.................. ....................... ....................... ...................... ....................... ....................... ...................... ...................... ................................ .....................31 31 (1emplo de e1erci*o a reali*ar na proba práctica a reali*ar ao rematar a "&D&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&3! $utoavaliación&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&33
Páxina 3 de 36
Páxina 4 de 36
1. Ficha técnica Contexto da actividade Módulo
Durac ión
MP0(1)% Desenvolvemento *eb en contorno servidor%
1+&
#nidade did$ctica%
#D0(% Proramación de aplicacións *eb con acceso a bases de datos
esió ns &0'
-.
Actividades
esió ns &0'
A01% Acceso a base de datos My!"%
1.
A0-% Acceso a base de datos empreando PD/%
10
NOTA: Esta actividade está vinculada á programación recollida no arquivo CSIFC03_MP0613_UD06_A01.pdf
Título da actividade
23tulo
Descrición
Duración
$0!
$cceso a base de datos M9S:'
-esta actividade e1plicarase como reali*ar operacións sobre bases de datos centrándose no sistema 1estor de base de datos M9S:' coa e1tensión m9s.li&
!=
Resultados de aprendizaxe do currículo 4esultados de aprendi5a6e do curr3culo
7ompleto
+$& Desenvolve aplicacións de acceso a almac)ns de datos5 aplicando medidas para manter a se#uridade e a inte#ridade da información
on
Obxectivos didácticos e título e descrición da actividade /b6ectivos espec3ficos 4!&!
Identificar as tecnolo1,as .ue $! permiten o acceso mediante pro#ramación á información dispo>ible en almac)ns de datos&
4!&<
Crear aplicacións .ue estable*an cone1ións con bases de datos&
4!&3
+ecuperar información dun?a
Actividade $cceso a base de datos M9S:'
Páxina 5 de 36
Descrición b$sica
Duración
-esta actividade e1plicarase como reali*ar operacións sobre bases de datos centrándose no sistema 1estor de base de datos M9S:' coa e1tensión m9s.li&
!=
base de datos e visuali*ala nun?a pá1ina web& 4!&=
Crear aplicacións web .ue permitan a actuali*ación e a eliminación de información dispo>ible nun?a base de datos&
4!&2
"sar transaccións para manter a consistencia da información&
Criterios de avaliación 7riterios de avaliación
C$&! @ $nali*áronse as tecnolo1,as .ue permitan o acceso mediante pro#ramación á información dispo>ible en almac)ns de datos& C$&<&! @ Creáronse aplicacións .ue estable*an cone1ións con bases de datos empre#ando m9s.li C$&3&! @ +ecuperouse información almacenada en bases de datos empre#ando m9s.li C$&= @ Publicouse en aplicacións web a información recuperada& C$&2 @ "tili*áronse con1untos de datos para almacenar a información& C$&&! @ Creáronse aplicacións web .ue permitan a actuali*ación e a eliminación de información dispo>ible nun?a base de datos empre#ando m9s.li C$&6&! @ "tili*áronse transaccións para manter a consistencia da información empre#ando m9s.li C$&7 @ Probáronse e documentáronse as aplicacións& C$&; @ Identificouse a necesidade do uso de consultas preparadas
Contidos 7ontidos
(stablecemento de cone1ións con bases de datos relacionais& – $PIs de P8P para acceder ás bases de datos de M9S:' – $ e1tensión m9s.li – Confi#uración de m9s.li – Cone1ión á base de datos – (rros +ecuperación e edición de información& %isuali*ación da información en pá1inas web& "so de con1untos de resultados& Mecanismos de edición da información nun cliente web& (1ecución de senten*as S:'& ransaccións& Consultas preparadas
Páxina 6 de 36
2. A1. Acceso a base de datos MySQL 1.1 Introdución Esta actividade ten como obxectivos: Identificar as tecnoloxías que permiten o acceso mediante programación á información dispoñible en almacéns de datos. Crear aplicacións que establezan conexións con bases de datos. Recuperar información dunha base de datos e visualizala nunha páxina web. Crear aplicacións web que permitan a actualización e a eliminación de información dispoñible nunha base de datos. Usar transaccións para manter a consistencia da información.
1.2 Actividade Acceso a base de datos
Como xa temos visto, unha API (Interface de Programación de Aplicacións) define as clases, métodos, funcións e variables que a aplicación necesita empregar para realizar unha tarefa concreta. No caso de aplicacións de PHP que necesiten acceder a unha base de datos, as APIs necesarias son extensións de PHP. As APIs poden ser procedimentais ou orientadas a obxectos. Unha API procedimental usará funcións para realizar tarefas, mentres que unha API orientada a obxectos instanciará clases e chamará aos métodos sobre os obxectos resultantes. PHP soporta máis de 15 sistemas xestores de bases de datos: SQLite, Oracle, SQL Server, PostgreSQL, IBM DB2, MySQL, etc. Ata a versión 5 de PHP, o acceso ás bases de datos facíase principalmente utilizando extensións específicas para cada sistema xestor de base de datos (extensións nativas). É dicir, que se queriamos acceder a unha base de datos de PostgreSQL, deberiamos instalar e utilizar a extensión dese xestor en concreto. As funcións e obxectos a utilizar eran distintos para cada extensión. A partir da versión 5 de PHP introduciuse na linguaxe unha extensión para acceder dunha forma común a distintos sistemas xestores: PDO. A gran vantaxe de PDO está clara: podemos seguir utilizando unha mesma sintaxe aínda que cambiemos o motor da nosa base de datos. Pola contra, nalgunhas ocasións preferiremos seguir usando extensións nativas nos nosos programas. Mentres PDO ofrece un conxunto común de funcións, as extensións nativas normalmente ofrecen máis potencia (acceso a funcións específicas de cada xestor de base de datos) e nalgúns casos tamén maior velocidade. Dos distintos SXBD existentes imos traballar con MySQL. MySQL é un xestor de bases de datos relacionais de código aberto baixo licenza GNU GPL. É o xestor de bases de datos máis empregado coa linguaxe PHP. APIs de PHP para acceder ás bases de datos de MySQL
Existen varias opcións dispoñibles para conectarse a un servidor MySQL dende unha aplicación en PHP. PHP ofrece 3 APIs diferentes ellas son mysql, mysqli, y PDO. Páxina 8 de 36
Tradicionalmente as conexións entre PHP e MySQL establecíanse utilizando a extensión nativa mysql. Esta extensión mantense na actualidade para dar soporte ás aplicacións xa existentes que a utilizan, pero non se recomenda utilizala para desenvolver novos programas, xa que foi declarada obsoleta a partir de PHP 5.5.0 e vai ser eliminada no futuro. O máis habitual é elixir entre mysqli (extensión nativa) e PDO. Con calquera de ambas as dúas extensións, poderás realizar accións sobre as bases de datos como: Establecer conexións. Executar sentenzas SQL. Obter os rexistros afectados ou devoltos por unha sentenza SQL. Empregar transaccións. Executar procedementos almacenados. Xestionar os erros que se produzan durante a conexión ou no establecemento desta. PDO e mysqli (e tamén a antiga extensión mysql) utilizan un driver de baixo nivel para comunicarse co servidor MySQL. Ata hai pouco o único driver dispoñible para realizar esta función era libmysql, que non estaba optimizado para ser utilizado dende PHP. A partir da versión 5.3, PHP vén preparado para utilizar tamén un novo driver mellorado para realizar esta función, o Driver Nativo de MySQL, mysqlnd. A extensión mysqli
A extensión mysqli, tamén coñecida como extensión de MySQL mellorada, desenvolveuse para aproveitar as novas funcionalidades encontradas nos sistemas MySQL con versión 4.1.3 ou posterior. Ven incluída nas versións PHP5 e posteriores, e conta coas seguintes melloras con respecto á extensión mysql:
Interface orientada a obxectos Soporte para consultas preparadas. Soporte para transaccións. Mellores opcións de depuración.
Configuración de MySQLi
No ficheiro php.ini hai unha sección específica para as opcións de configuración propias de cada extensión. Entre as opcións que se poden configurar para a extensión MySQLi están: mysqli.allow_persistent: Permite crear conexións persistentes.
Número de porto TCP predeterminado a utilizar cando se conecta ao servidor de base de datos. mysqli.reconnect: Indica se se debe volver conectar automaticamente en caso de que se perda a conexión. mysqli.default_host: Host predeterminado a usar cando se conecta ao servidor de base de datos. mysqli.default_user: Nome de usuario predeterminado a usar cando se conecta ao servidor de base de datos. mysqli.default_pw: Contrasinal predeterminado a usar cando se conecta ao servidor de base de datos. mysqli.default_port:
Páxina 9 de 36
Conexión á base de datos
Para poder acceder aos datos dunha base de datos, previamente temos que establecer unha conexión co servidor MySQL. Con MySQLi, existen dous xeitos de establecer unha conexión co servidor: Crear unha instancia da clase mysqli. O construtor da clase pode recibir seis parámetros, todos opcionais, aínda que o máis habitual é utilizar os catro primeiros: o o nome ou dirección IP do servidor MySQL ao que che queres conectar. o un nome de usuario con permisos para establecer a conexión. o o contrasinal do usuario. o o nome da base de datos á que conectarse. o o número do porto en que se executa o servidor MySQL. o o socket ou a canalización con nome (named pipe) a usar. $db = new mysqli('localhost', 'usuario', 'contrasinal', 'base_datos');
Ou tamén podemos facer: $db = new mysqli(); $db->connect('localhost', 'usuario', 'contrasinal', 'base_datos');
Obter unha instancia da clase mysqli é empregando a función mysqli_connect: $db = mysqli_connect('localhost', 'usuario', 'contrasinal', 'base_datos');
Ou tamén podemos establecer a conexión co servidor e seleccionar a continuación a base de datos empregando a función mysqli_select_db: $db=mysqli_connect('localhost', 'usuario', 'contrasinal'); mysqli_select_db('base_datos',$db);
A function mysqli_select_db tamén a podemos usar para cambiar a base de datos coa que imos traballar. Para isto tamén se pode usar o método select_db como se ve a continuación: $db->select_db("outra_bd");
Comprobar .ue a cone1ión se estableceu correctamente
É importante verificar que a conexión se estableceu correctamente antes de realizar ningunha operación sobre a base de datos. Para comprobar o erro, en caso de que se produza, podes usar as seguintes propiedades (ou funcións equivalentes) da clase mysqli: P4/PIEDADE
F#7I<
connect/errno
m9s.li/connect/errnoA B
Devolve o nmero de erro 1erado polo ltimo intento de cone1ión5 ou null se non se produce nin#n erro&
connect/error
m9s.li/connect/errorA B
Devolve a mensa1e de erro 1erada polo ltimo intento de cone1ión5 ou null se non se produce nin#n erro&
Por exemplo, o seguinte código comproba o establecemento dunha conexión coa base de datos "Empresa" e finaliza a execución se se produce algún erro: Páxina 10 de 36
$db = new mysqli('localhost', 'usuario', 'contrasinal', 'Empresa'); $error = $db->connect_errno; if ($error != null) { echo "
Erro $error conectando á base de datos: $db->connect_error
"; exit(); }
Pec?ar a cone1ión á base de datos
Para pechar a conexión a base de datos podemos emplear a función mysqli_close como se amosa a continuación: mysqli_close($db);
ou empregando o estilo orientado a obxectos podemos invocar o método close() e polo tanto escribir algo como: $db->close();
Na tarefa 1 crearemos a base de datos coa que imos traballar nesta unidade didáctica e estableceremos unha conexión con esta empregando a extensión mysqli. Erros
Xa vimos as funcións que nos permiten controlar os erros producidos na conexión á base de dato. A extensión MySQLi proporciona procedementos e propiedades de obxecto que dan información do último erro producido na base de datos: P4/PIEDADE
F#7I<
errno
m9s.li/errnoAm9s.li conB
Devolve o nmero de erro 1erado na base de datos5 ou null se non se produce nin#n erro&
error
m9s.li/errorAm9s.li conB
Devolve a ltima mensa1e de erro 1erada na base de datos5 ou null se non se produce nin#n erro&
Execución de consultas
Ao igual que cando fixemos a conexión á base de datos, podemos executar consultas empregando mysqli de xeito procedimental e orientado a obxectos. Ademáis, imos distinguir dous tipos de consultas: as que devolven valores e as que non os devolven. Consultas .ue non devolven valores
A execución de consultas de creacción e eliminación de bases de datos ou táboas (CREATE e DROP), e de actualización da información da base de datos (UPDATE, INSERT e DELETE) non devolve ningún valor almacenado na base de datos. Unicamente devolverá true ou false para indicar se se ten producido algún erro. A forma máis inmediata de executar unha consulta con MySQLi é o método query, empregando o estilo orientado a obxectos, ou a función mysqli_query co estilo procedimental. Imos ver primeiro un exemplo de execución de consulta empregando o estilo orientado a obxectos. Neste caso, a propiedade affected_rows conterá o número de filas afectadas pola última consulta de actualización executada. $sentenza = "DROP TABLE IF EXISTS libro";
No seguinte exemplo insertamos unha fila na base de datos e comprobamos que o número de filas afectadas é 1 empregando a propiedade affected_rows. (Pode ser que a sintaxe sexa correcta e a consulta funcione, pero que non produzca o resultado esperado) $sentenza = "INSERT INTO provincia (codigo, nome) VALUES ('37', 'Salamanca')"; $db->query($sentenza); if($db->errno) {die(' ERRO('.$db->errno.') ->'.$db->error);} if($db->affected_rows!=1) {die ('Error: non é o resultado esperado.');}
O equivalente procedemental, para o método query da interface orientada a obxectos é a función mysqli_query(mysqli $link, string $consulta) que devolve true no caso de que non se produza ningún erro e false en caso contrario. Para consultar o número de filas afectadas pola consulta temos a función mysqli_affected_rows(mysqli $link). $sentenza = "INSERT INTO provincia (codigo, nome) VALUES ('08', 'Barcelona')"; $resultado= mysqli_query($db, $sentenza); if(mysqli_errno($db)) {die(' ERRO('.mysqli_errno($db).') ->'.mysqli_error($db));} if(mysqli_affected_rows($db)!=1) {die ('Error: non é o resultado esperado.');}
Cando realizamos unha inserción pode ser que o identificador da táboa sexa autoincremental, co cal non temos que definilo cando facemos a inserción pero podemos querer saber cal foi o último valor que se insertou. Para facer isto, temos a propiedade insert_id cando estamos traballando coa interface orientada a obxectos, e a función mysqli_insert_id(mysqli $link) para o estilo procedemental. Na tarefa 2 realizaremos consultas de acción sobre a base de datos receitas. Consultas .ue devolven valores
A execución dunha senteza SELECT sobre a base de datos devolve un conxunto de resultados que haberá que procesar ou mostrar. Para a execución destas consultas empréganse os mesmos métodos que os explicados para as consultas de acción: query se usamos a interface orientada a obxectos e a función mysqli_query co estilo procedimental. Os datos devólvense en forma dun obxecto da clase mysqli_result. Ademáis, se queremos coñecer o número de filas que contén o resultado da consulta podemos empregar o método num_rows da clase mysqli_result para a interface orientada a obxectos, e mysqli_num_rows(mysqli_result $result) para a interface procedimental. A continuación vemos os métodos máis comúns de manexar a información devolta: Array asociativo: array mysqli_result::fetch_assoc( void ) Este método manexa os datos de cada fila nun array asociativo, onde o nome de cada columna é o índice. Haberá que crear un bucle para recorrer as filas e amosar o resultado: $db = new mysqli("localhost", "alumno", "abc123.", "receitas"); $sql = "SELECT chef.nomeartistico as chef, receita.nome as receita
Páxina 12 de 36
FROM chef LEFT JOIN receita ON chef.codigo=cod_chef"; $resultado = $db->query($sql); if($db->errno) {die(' ERRO('.$db->errno.') ->'.$db->error);} while($fila = $resultado -> fetch_assoc()){ echo "CHEF: ".$fila['chef'] . " --> RECEITA:".$fila['receita'] ." "; }
O equivalente en estilo procedemental sería o array asociativo mysqli_fetch_assoc ( mysqli_result $result ). Neste caso, o parámetro de entrada é o resultado de mysqli_query() e non unha conexión. $db = mysqli_connect("localhost", "alumno", "abc123.", "receitas"); $sql = "SELECT chef.nomeartistico as chef, receita.nome as receita FROM chef LEFT JOIN receita ON chef.codigo=cod_chef"; $resultado = mysqli_query($db, $sql); if(mysqli_errno($db)) {die(' ERRO('.mysqli_errno($db).') ->'.mysqli_error($db));} while($fila = mysqli_fetch_assoc($resultado)){ echo "CHEF: " . $fila['chef'] . "--> RECEITA:".$fila['receita'] ." "; }
Array asociativo, numérico ou ambos:
mixed mysqli_result::fetch_array ([ int
$tiporesultado = MYSQLI_BOTH ] )
Este método obtén os datos de cada fila como un array asociativo, numérico ou ambos dependendo do parámetro que se lle pase. Os posibles valores son: o MYSQLI_BOTH: é o valor por defecto. Devolve un array mixto de índices numéricos e claves (nomes das columnas). Array ( [0] => XULIANICO [chef] => XULIANICO [1] => AMEIXAS VERDES [receita] => AMEIXAS VERDES)
o MYSQLI_ASSOC: Devolve un array asociativo. Os nomes das columnas serán as
o MYSQLI_NUM: Devolve un array numérico. Cada índice representa o contido das
columnas da consulta na orde na que están especificadas nesta. Array ( [0] => XULIANICO [1] => AMEIXAS VERDES)
Para amosar todas as columnas teremos que facer de xeito similar ao método anterior, indicando a clave en función do parámetro que se lle pase: while($fila = $resultado -> fetch_array(MYSQLI_ASSOC)){ echo "CHEF: ".$fila['chef'] . " --> RECEITA:".$fila['receita'] ." "; }
O equivalente en estilo procedemental sería o array
Este método obtén cada fila de resultados como se fose un obxecto, onde $nome_clase é o nome da clase a instanciar (opcional) e $params é un array opcional de parámetros a pasar ao construtor de dita clase. while ($obxecto = $resultado->fetch_object()) { echo $obxecto->chef . " --> " . $obxecto->receita . " "; }
A vantaxe de usar este método é que nos permite instanciar unha clase, a que lle pasamos os datos da fila do obxecto, e que nos permite definir métodos para traballar con estes. S campos da fila pasan a ser atributos públicos da clase, co cal poderemos acceder a estes dentro da clase sen necesidade de definilos. Por exemplo, se temos unha clase Consulta que recibe o resultado da nosa consulta, automáticamente esta terá como atributos públicos chef e receita, co cal podemos definir un método para amosalos como se ve a continuación: class Consulta { function amosar(){ return " " . $this->chef . " --> " . $this->receita; } }
E para amosar o contido usamos o método feth_object ao que lle pasamos a clase creada para recoller o resultado: $resultado = $db->query($sql); while($fila = $resultado -> fetch_object("Consulta")){ echo $fila->amosar(); }
Inda que poda parecer extraño querer obter o resultado dunha fila da consulta como un obxecto cando utilizamos o interface procedimental, tamén se pode facer usando object mysqli_fetch_object (mysqli_result $result [,string $class_name[, array $params ]]). E ao igual que coa interface orientada a obxetos tamén lle podemos indi-
car a clase que queremos instanciar e os parámetros que lle pasamos ao constructor desa clase. while ($obxecto = mysqli_fetch_object($resultado)) { echo $obxecto->chef . " --> " . $obxecto->receita . " "; }
É importante ter en conta que os resultados obtidos se almacenarán en memoria mentres os esteas a usar. Cando xa non os necesites, pódelos liberar co método free da clase mysqli_result (ou coa función mysqli_free_result). $resultado->free();
Na tarefa 3 realizaremos consultas que devolven valores sobre a base de datos receitas.
Páxina 14 de 36
Transaccións
Cando traballamos con bases de datos pode suceder que nalgunhas ocasións queiramos que X operacións se executen como un bloque, isto é, que ou ben se executen todas correctamente, ou, se algunha falla, non queremos que se rexistre ningún cambio na base de datos. Para isto debemos usar transaccións. Os motores de almacenamento de tablas en MySQL son MyISAM e InnoDB. O que funciona por defecto é o motor MyISAM, que exclúe a seguridade proporcionada pola integridade referencial e non permite transaccións. Por isto, para traballar con transaccións debemos traballar co motor InnoDB. Por defecto, MySQL execútase en modo de execución automática (autocommit), o que significa que cada consulta individual inclúese dentro da súa propia transacción. O que conleva que tan pronto como se executa unha sentenza, se modifica a táboa de MySQL, facendo imposible a volta atrás. Para poder revertir os cambios das consultas (rollback) usando transaccións, debemos desctivar o modo de execución automática, o que iniciará a transacción. $db->autocommit(false);
Ou co estilo procedemental: mysqli_autocommit($db, false);
O importante cando traballamos con transaccións é que o programador ten o control de cando facer efectiva a modificación ou de revertir as modificacións ocasionadas polas consultas. Para facer efectiva as modificacións chamaremos a función commit coa interface orientada a obxectos e mysqli_commit (mysqli $link) coa interface procedimental. E para revertir a transacción actual chamaremos á función rollback coa interface procedimental e mysqli_rollback (mysqli $link) coa interface procedimental. A continuación imos ver un exemplo de transacción coa interface orientada a obxectos para insertar un novo chef do que non estaba dada de alta a provincia: $db = new mysqli("localhost", "alumno", "abc123.", "receitas"); if ($db->connect_error) { echo "Erro na conexión a base de datos"; exit; } else { $bandeira=true; $db->autocommit(FALSE); $sql1="INSERT INTO PROVINCIA (CODIGO, NOME) VALUES ('45','Toledo')"; $sql2="INSERT INTO CHEF (CODIGO, NOME, APELIDO1, SEXO, LOCALIDADE, COD_PROVINCIA) VALUES (12,'ANTÍA','NOGUEIRA','M','Toledo','45')"; $result = $db->query($sql1); if ($db->errno) { $bandeira = false; echo ' ERRO na primeira operación ('.$db->errno.')->'.$db->error; } $result = $db->query($sql2); if ($db->errno) { $bandeira = false; echo ' ERRO na segunda operación ('.$db->errno.')->'.$db->error; } if ($bandeira == true){ $db->commit(); echo 'Transacción executada con éxito!.'; } else { $db->rollback(); echo '
Erro nalgún punto da transacción.
'; } $db->close();
Páxina 15 de 36
}
O mesmo exemplo coa interface procedemental sería: $db = mysqli_connect("localhost", "alumno", "abc123.", "receitas"); if (mysqli_connect_error($db)) { echo "Erro na conexión a base de datos"; exit; } else { $bandeira=true; mysqli_autocommit($db, FALSE); $sql1="INSERT INTO PROVINCIA (CODIGO, NOME) VALUES ('45','Toledo')"; $sql2="INSERT INTO CHEF (CODIGO, NOME, APELIDO1, SEXO, LOCALIDADE, COD_PROVINCIA) VALUES (12,'ANTÍA','NOGUEIRA','M','Toledo','45')"; $result = mysqli_query($db, $sql1); if (mysqli_errno($db) != 0) { $bandeira = false; echo ' ERRO na primeira operación ('.mysqli_errno($db). ') ->'. mysqli_error($db); } $result = mysqli_query($db, $sql2); if (mysqli_errno($db) != 0) { $bandeira = false; echo ' ERRO na segunda operación ('. mysqli_errno($db). ') ->'. mysqli_error($db); } }
if ($bandeira == true){ mysqli_commit($db); echo 'Transacción executada con éxito!.'; } else { mysqli_rollback($db); echo '
Erro nalgún punto da transacción.
'; } mysqli_close($db);
É importante ter en conta algunhas cousas cando se traballa con transaccións: O rollback unicamente afecta as operacións de manipulación de datos, é dicir, DELETE, INSERT e UPDATE. Non afecta a CREATE, DROP ou ALTER. Se temos un campo auto_increment e durante a transacción se fai algún insert con éxito, e posteriormente falla algunha operación realizada na mesma transacción, dando lugar á execución dun rollback, o campo auto_increment terá o contador como se os inserts sí houbesen tido lugar. O rollback non o restaura ao valor inicial. Para facelo deberiamos executar un ALTER TABLE para establecer o valor ao seu estado actual.
Na tarefa 4 realizaremos operacións que impliquen o uso de transaccións. Consultas preparadas
Cada vez que se envía unha consulta ao servidor, este debe analizala antes de executala. Algunhas sentenzas SQL, como as que insiren valores nunha táboa, deben repetirse de forma habitual nun programa. Para acelerar este proceso, MySQL admite consultas preparadas. Estas consultas almacénanse no servidor listas para ser executadas cando sexa necesario e presentan as seguintes vantaxes: Optimización: xa que reducen o gasto de recursos na análise e execución de cada consulta. Seguridade: xa que ofrecen máis seguridade ante posibles inxeccións de SQL. Páxina 16 de 36
Para traballar con consultas preparadas coa extensión MySQLi de PHP empregando a interface orientada a obxectos, debes utilizar a clase mysqli_stmt. Utilizando o método stmt_init da clase mysqli obtense un obxecto da devandita clase. Os pasos que debes seguir para executar unha consulta preparada coa interface orientada a obxectos son: Preparar a consulta no servidor MySQL utilizando o método prepare.
Executar a consulta, tantas veces como sexa necesario, co método execute. Unha vez que xa non se necesita máis, débese executar o método close. Imos ver un exemplo: $consulta = $db->stmt_init(); $consulta->prepare('INSERT INTO PROVINCIA (codigo, nome) VALUES ("50", "Zaragoza")'); $consulta->execute(); $consulta->close(); $db->close();
O problema é que de pouco serve preparar unha consulta de inserción de datos como a anterior, se os valores que insire son sempre os mesmos. Por este motivo as consultas preparadas admiten parámetros. Para preparar unha consulta con parámetros, en lugar de poñer os valores debes indicar cun signo de interrogación a súa posición dentro da sentenza SQL. $consulta->prepare('INSERT INTO PROVINCIA (codigo, nome) VALUES (?, ?) ');
E antes de executar a consulta tes que utilizar o método bind_param para substituír cada parámetro polo seu valor. O primeiro parámetro do método bind_param é unha cadea de texto na que cada carácter indica o tipo dun parámetro, segundo a seguinte táboa: 7A4A72E4
2IP/ D/ PA4=ME24/
I
-mero enteiro
D
-mero real Adobre precisiónB
S
Cadea de te1to
Contido en formato binario A'4B
Por exemplo: $consulta = $db->stmt_init(); $consulta->prepare('INSERT INTO PROVINCIA (codigo, nome) VALUES (?, ?)'); $codigo = "50"; $provincia = "Zaragoza"; $consulta->bind_param('ss', $codigo, $provincia); $consulta->execute(); $consulta->close(); $db->close();
No caso das consultas que devolven valores temos que vincular as variables resultado da consulta preparada para almacenar o seu resultado. Temos dous métodos para extraer o resultado das columnas da consulta preparada: bind_result: vincula as columnas do resultado da columna coas variables que gardarán ese resultado. fetch: Permite obter os resultado desas variables, para o cal deberemos recorrer un bucle que permita obter os datos de todas as filas resultantes da consulta. Páxina 17 de 36
$consulta = $db->stmt_init(); $consulta->prepare('SELECT nome, dificultade, tempo FROM receita WHERE tempo<50'); $consulta->execute(); $consulta->bind_result($receita, $dificultade, $tempo); while($consulta->fetch()) { print "
$receita ( $dificultade ) - $tempo minutos
"; } $consulta->close(); $db->close();
Para empregar consultas preparadas coa extensión MySQLi de PHP empregando a interface procedemental usaremos a función mysqli_stmt_init(). Os pasos a seguir son os mesmos que se indicaron anteriormente, pero as funcións a empregar neste caso son: mysqli_stmt_prepare, mysqli_stmt_execute e mysqli_stmt_close respectivamente. Imos ver un exemplo: $sql = "INSERT INTO PROVINCIA (codigo, nome) VALUES (?, ?)"; $stmt = mysqli_stmt_init($db); if(mysqli_stmt_prepare($stmt,$sql)){ //para comprobar erros no prepare
A función para substituir cada parámetro polo seu valor é mysqli_stmt_bind_param : mysqli_stmt_bind_param($stmt, 'ss', $codigo, $provincia); $codigo = "50"; $provincia = "Zaragoza"; mysqli_stmt_execute($stmt); $codigo = "38"; $provincia = " Santa Cruz de Tenerife"; mysqli_stmt_execute($stmt); mysqli_stmt_close($stmt); } //fin do if do prepare
E para para asignar a variables os campos que se obteñen tras a execución temos mysqli_stmt_bind_result, usando mysqli_stmt_fetch() para recorrelos: $db = mysqli_connect("localhost", "alumno", "abc123.", "receitas"); $sql = "SELECT nome, dificultade, tempo FROM receita WHERE tempo<50"; $stmt = mysqli_stmt_init($db); if(mysqli_stmt_prepare($stmt,$sql)){ mysqli_stmt_execute($stmt); $receita = ""; $dificultade = ""; $tempo = 0; mysqli_stmt_bind_result($stmt,$receita, $dificultade, $tempo); while (mysqli_stmt_fetch($stmt)) { print "
$receita ( $dificultade ) - $tempo minutos
"; } mysqli_stmt_close($stmt); $db->close(); }
Na tarefa 5 realizaremos operacións con consultas preparadas.
Páxina 18 de 36
Tarefas As tarefas propostas son as seguintes. Tarefa 1_a. Creación e conexión a base de datos de traballo . Nesta tarefa crearemos a base de datos coa que imos traballar nesta unidade didáctica e estableceremos unha conexión con esta empregando a extensión mysqli. Tarefa 1_b. Creación dunha clase conexión. Nesta tarefa crearemos unha clase conexión para conectarse a unha base de datos que se pasa como parámetro no servidor local. Tarefa 2. Realización de consultas de acción . Nesta tarefa realizaremos consultas de acción sobre a base de datos receitas empregando a interface orientada a obxectos e o estilo procedemental. Tarefa 3. Realización de consultas que devolven valores . Nesta tarefa realizaremos consultas que devolven valores sobre a base de datos receitas. Tarefa 4. Realización de operacións que implican transaccións. Nesta tarefa realizaremos operacións que deban executarse como un único bloque. Tarefa 5. Realización de operacións con consultas preparadas . Nesta tarefa empregaremos consultas preparadas para axilizar a execución cando se realiza a mesma consulta en máis dunha ocasión.
Páxina 19 de 36
1.2.1 Tarefa 1. Creación e conexión a base de datos de traballo aB arefa !/a
Empregando o script crearReceitas.sql adxuntado como recurso crea a base de datos Receitas en mySQL, que será a que usaremos para aprender a traballar coas bases de datos. A continuación crea un usuario para esta base de datos de nome "alumno" e contrasinal "abc123.", e intenta conectarte dende php a base de datos, dando unha mensaxe indicando se a conexión se estableceu con éxito ou o erro producido ao conectarse. Pon un exemplo de conexión empregando estilo procedimental e outro empregando orientación a obxectos. bB arefa !/b
Crea unha clase de nome accesoBD na que o construtor recibe como parámetro a base de datos, o usuario e a contrasinal, e aemáis ten: Un método abrirConexion que devolve un obxecto coa conexión establecida á base de datos no servidor local. Un método pecharConexion que pecha a conexión coa base de datos Autoavaliación aB arefa !/a
O script podemos executalo dende phpMyAdmin, na pestaña SQL:
Unha vez creada a base de datos, seleccionámola e imos a pantalla de Privilexios:
Páxina 20 de 36
Nesta pantalla prememos en Agregar usuario para engadir o usuario alumno e marcamos a opción "Otorgar todos los privilegios para la base de datos receitas":
Isto engade o usuario alumno e otórgalle todos os privilexios sobre a base de datos receitas
Conexión á base de datos dende PHP empregando orientación a obxectos: connect_error) { printf("Fallou a conexión a base de datos receitas. ERRO(%d): %s\n", $db->connect_errno, $db->connect_error); exit(); } printf("Conectado a base de datos receitas con éxito"); $db->close(); ?>
Conexión á base de datos dende PHP empregando estilo procedimental:
Páxina 21 de 36
printf("Fallou a conexión a base de datos receitas. ERRO(%d): %s\n", mysqli_connect_errno(),mysqli_connect_error()); exit();
} printf("Conectado a base de datos receitas con éxito"); if(mysqli_close($db)){ print " Pechada a conexión coa base de datos"; } ?>
bB arefa !/b usuario=$usuario; $this->contrasinal=$contrasinal; $this->bd=$bd; } /** Método para establecer a conexión cunha base de datos **/ public function abrirConexion () { $con = new mysqli('localhost',$this->usuario,$this->contrasinal, $this->bd); if ($con ->connect_error) { echo "Erro na conexión a base de datos $this->bd: ($con->connect_errno) $con->connect_error\n"; exit; } return $con; } /** Método para pechar a conexión cunha base de datos **/ public function pecharConexion ($con) { $con->close(); } } ?>
1.2.2 Tarefa 2. Realización de consultas de acción. aB arefa
Crear unha táboa Libro coa seguinte estrutura na base de datos receitas, establecendo as regras de integridade que sexan necesarias, empregando a interface orientada a obxectos. Usa a clase conexión definida na tarefa 1_b. Atributo
Descripción
Codi#o
$utoincremental
itulo
Cont)n o t,tulo do libro& odos os libros deben ter un t,tulo& Poden e1istir dous libros co mesmo t,tulo&
(ditorial
Cont)n a editorial .ue publicou este li bro& E obri#atorio introducila para todos os libros&
Pa1inas
-mero de pá1inas de .ue consta o libro& Pode ser .ue non te>amos esta información
Cod/c?ef
Códi#o do c?ef .ue escribiu este libro& odos os libros foron escritos por un nico c?ef .ue debe e1istir na base de datos&
Páxina 22 de 36
bB arefa
Empregando estilo procedimental inserta o seguinte libro na base de datos: 'Receitas imaxinativas' da editorial 'Cociña hoxe', escrito polo chef ' EL TITO ' e do que non coñecemos o número de páxinas. Comproba que se realizou a inserción dunha fila na táboa e imprime a seguinte información : "Inserido 1 rexistro co código XX". Autoavaliación aB arefa abrirConexion(); $consulta='CREATE TABLE libro (codigo SMALLINT NOT NULL AUTO_INCREMENT, titulo VARCHAR(100) NOT NULL, editorial VARCHAR(50) NOT NULL, paxinas SMALLINT NULL, cod_chef tinyint NOT NULL, CONSTRAINT pk_libro PRIMARY KEY(codigo), CONSTRAINT fk_libro_chef FOREIGN KEY(cod_chef) REFERENCES chef(codigo));'; $mysqli->query($consulta); if($mysqli->errno) {die(' ERRO('.$mysqli->errno.') ->'.$mysqli->error);} $con->pecharConexion($mysqli); ?>
bB arefa ERRO('.mysqli_errno($db).') ->'.mysqli_error($db));} /* comprobamos que o número de filas afectadas foi 1 */ if(mysqli_affected_rows($db)!=1) {die ('Error: non é o resultado esperado.');} else {printf(" Inserido %d rexistro co código %d",mysqli_affected_rows($db), mysqli_insert_id($db));} mysqli_close($db); ?>
Páxina 23 de 36
1.2.3 Tarefa 3. Realización de consultas de selección aB arefa 3/a
Fai un script que lea da base de datos a seguinte información relativa as receitas e a amose según se ve na imaxe: o A información debe de visualizarse páxinada (No exemplo, a variable que indica o número de rexistros por páxinas ten valor 5)
bB arefa 3/b
Fai un script que cargue un desplegable coa información das provincias cB arefa 3/c
Imos ampliar a tarefa anterior. Cando se seleccione unha provincia cargarase unha páxina con información da provincia como se amosa na seguinte imaxe:
'; //enlaces para o paxinado for($i=0; $i<$totalPaxinas;$i++){ echo ''.($i+1).' | '; } echo '
' ?>
bB arefa 3/b connect_error) {die('Error de conexión: ' . $db->connect_error);} $sql="SELECT * from provincia"; $resultado = $db->query($sql); if ($resultado->num_rows > 0) { $combo=""; while ($row = $resultado->fetch_array(MYSQLI_ASSOC)) { $combo .= " "; } } else {
Páxina 25 de 36
echo "A táboa Provincia non ten datos"; } $db->close(); ?> Selección por provincia
cB arefa 3/c arefa3c&p?p connect_error) {die('Error de conexión: ' . $db->connect_error);} $sql="SELECT * from provincia"; $resultado = $db->query($sql); if ($resultado->num_rows > 0) { $combo=""; while ($row = $resultado->fetch_array(MYSQLI_ASSOC)) { $combo .=" "; } } else { echo "A táboa Provincia non ten datos"; } $db->close(); //cerramos la conexión ?> Selección por provincia
arefa3c/<&p?p Cociñeiros da provincia.
Páxina 26 de 36
mysqli_connect_error($db)\n"; exit; } $sql = "select nome from provincia where codigo = '$provincia'"; $resultado = mysqli_query($db, $sql); if(mysqli_errno($db)) {die(' ERRO('.mysqli_errno($db).') ->'.mysqli_error($db));} $fila = mysqli_fetch_assoc($resultado); echo '
1.2.4 Tarefa 4. Realización de operacións que implican transaccións O chef con nome artístico SEOANE creou unha nova receita de nome 'ENSALADA ESPECIAL' catalogada como 'ENTRANTE' e con dificultade 'MEDIA'. Esta receta consta dos seguintes ingredientes: o Garavanzos: 200 gramos o Pementos: 70 gramos o Cebola:40 gramos o Sal: 1 pizca. Garda esta información na base de datos tendo en conta que non queremos que a receta quede almacenada 'a medias'. Ademáis, o programa debe indicar, no caso de terse producido algún erro, a operación na que se produciu ese erro e cal é a descrición deste. Autoavaliación /** Inserción dunha nova receita empregando transaccións **/ $db = new mysqli("localhost", "alumno", "abc123.", "receitas"); if ($db->connect_error) { die ('Erro na conexión á base de datos.'); } else { $bandeira=true; $sql="SELECT MAX(CODIGO)+1 AS COD FROM RECEITA"; $resultado = $db->query($sql); $fila = $resultado -> fetch_array(); $codigo=$fila["COD"]; $db->autocommit(FALSE); $sql1="INSERT INTO RECEITA (CODIGO,NOME, COD_GRUPO, DIFICULTADE, COD_CHEF) VALUES (".$codigo.",'ENSALADA ESPECIAL', (SELECT CODIGO FROM GRUPO WHERE NOME='ENTRANTES'),'Media', (SELECT CODIGO FROM CHEF WHERE NOMEARTISTICO='SEOANE'))"; $resultado = $db->query($sql1); if ($db->errno) { $bandeira = false;
Páxina 27 de 36
}
echo ' ERRO na primeira operación ('.$db->errno.')->'.$db->error; } $sql2="INSERT INTO RECEITA_INGREDIENTE (COD_RECEITA, COD_INGREDIENTE, CANTIDADE, MEDIDA) VALUES (".$codigo.",(SELECT CODIGO FROM INGREDIENTE WHERE NOME='GARAVANZOS'),200,'gramos')"; $resultado = $db->query($sql2); if ($mysqli->errno) { $bandeira = false; echo ' ERRO na segunda operación ('.$db->errno.')->'.$db->error; } $sql3="INSERT INTO RECEITA_INGREDIENTE (COD_RECEITA, COD_INGREDIENTE, CANTIDADE, MEDIDA) VALUES (".$codigo.",(SELECT CODIGO FROM INGREDIENTE WHERE NOME='PEMENTOS'),70,'gramos')"; $resultado = $db->query($sql3); if ($mysqli->errno) { $bandeira = false; echo ' ERRO na terceira operación ('.$db->errno.')->'.$db->error; } $sql4="INSERT INTO RECEITA_INGREDIENTE (COD_RECEITA, COD_INGREDIENTE, CANTIDADE, MEDIDA) VALUES (".$codigo.",(SELECT CODIGO FROM INGREDIENTE WHERE NOME='CEBOLA'),40,'gramos')"; $resultado = $db->query($sql4); if ($mysqli->errno) { $bandeira = false; echo ' ERRO na cuarta operación ('.$db->errno.')->'.$db->error; } $sql5="INSERT INTO RECEITA_INGREDIENTE (COD_RECEITA, COD_INGREDIENTE, CANTIDADE, MEDIDA) VALUES (".$codigo.",(SELECT CODIGO FROM INGREDIENTE WHERE NOME='SAL'),1,'pizca')"; $resultado = $db->query($sql5); if ($mysqli->errno) { $bandeira = false; echo ' ERRO na quinta operación ('.$db->errno.')->'.$db->error; } if ($bandeira == true){ $db->commit(); echo 'Transacción executada con éxito!.'; } else { $db->rollback(); echo '
Erro nalgún punto da transacción.
'; } $db->autocommit(TRUE); $db->close();
1.2.5 Tarefa 5. Realización de operacións con consultas preparadas Modifica a tarefa 4 para que empregue consultas preparadas cando o consideres necesario. Autoavaliación arefa2&p?p connect_error) { die ('Erro na conexión á base de datos.'); } else { $bandeira=true; $sql="SELECT MAX(CODIGO)+1 AS COD FROM RECEITA"; $resultado = $db->query($sql); $fila = $resultado -> fetch_array(); $codigo=$fila["COD"]; $db->autocommit(FALSE); $sql1="INSERT INTO RECEITA (CODIGO,NOME, COD_GRUPO, DIFICULTADE, COD_CHEF) VALUES (".$codigo.",'ENSALADA ESPECIAL',
Páxina 28 de 36
(SELECT CODIGO FROM GRUPO WHERE NOME='ENTRANTES'),'Media', (SELECT CODIGO FROM CHEF WHERE NOMEARTISTICO='SEOANE'))"; $resultado = $db->query($sql1); if ($db->errno) { $bandeira = false; echo ' ERRO na primeira operación ('.$db->errno.')->'.$db->error; } /** Como temos que insertar varios ingredientes para cada receta faremos * unha consulta preparada**/ $stmt = $db->stmt_init(); if (!$stmt->prepare('INSERT INTO RECEITA_INGREDIENTE (COD_RECEITA, COD_INGREDIENTE, CANTIDADE, MEDIDA) SELECT ?, CODIGO, ?, ? FROM INGREDIENTE WHERE NOME=?')) { echo "Fallou o prepare de stmt: (" . $db->errno . ") " . $db->error; } if (!$stmt->bind_param('iiss', $codigo, $cantidade, $medida , $ingrediente)) { echo "Fallou a vinculación de parámetros: (" . $db->errno . ") " . $db->error; } $cantidade = 200; $medida='gramos'; $ingrediente='GARAVANZOS'; $stmt->execute(); if ($db->errno) { $bandeira = false; echo ' ERRO na segunda operación ('.$db->errno.')->'.$db->error; }
} ?>
$cantidade = 70; $medida='gramos'; $ingrediente='PEMENTOS'; $stmt->execute(); if ($db->errno) { $bandeira = false; echo ' ERRO na terceira operación ('.$db->errno.')->'.$db->error; } $cantidade = 40; $medida='gramos'; $ingrediente='CEBOLA'; $stmt->execute(); if ($db->errno) { $bandeira = false; echo ' ERRO na cuarta operación ('.$db->errno.')->'.$db->error; } $cantidade = 1; $medida='pizca'; $ingrediente='SAL'; $stmt->execute(); if ($db->errno) { $bandeira = false; echo ' ERRO na cuarta operación ('.$db->errno.')->'.$db->error; } if ($bandeira == true){ $db->commit(); echo 'Transacción executada con éxito!.'; } else { $db->rollback(); echo '