web-dev-qa-db-fra.com

Bouton pour exécuter une requête mysql

J'ai fait une requête mysql qui va copier 3 colonnes de données d'une table à une autre:

INSERT INTO eio3k_hikers (link_id, link_name, user_id) SELECT link_id, link_name, user_id FROM eio3k_mt_links where eio3k_mt_links.link_id = (3)

J'ai créé un bouton qui, une fois cliqué, devrait exécuter la requête. Mon code ressemble à ceci:

<html>
<form action='' method='POST'>
    <input type='submit' name='submit' />
</form>
</html>

<?php 
define('_JEXEC', 1);
define('DS', DIRECTORY_SEPARATOR);

if (file_exists(dirname(__FILE__) . '/defines.php')) {
    include_once dirname(__FILE__) . '/defines.php';
}

if (!defined('_JDEFINES')) {
    define('JPATH_BASE', dirname(__FILE__));
    require_once JPATH_BASE.'/includes/defines.php';
}
require_once JPATH_BASE.'/includes/framework.php';

// Get a db connection.
$db = JFactory::getDbo();

if(isset($_POST['submit'])){
    // My query 
    $querySelect = $db->getQuery(true);
    $querySelect->select('link_id, link_name, user_id');
    $querySelect->from($db->quoteName('#__mt_links'));
    $querySelect->where($db->quoteName('#__mt_links.link_id')." = ".$db->quote(3));

    $queryInsert = $db->getQuery(true);
    $queryInsert->insert($db->quoteName('#__hikers'));
    $queryInsert->columns($db->quoteName(array('link_id, link_name, user_id')));
    $queryInsert->values($querySelect);
    $db->setQuery($queryInsert);
}

Lorsque je clique sur le bouton, les données ne sont pas insérées. J'ai aussi essayé ceci dans la dernière ligne:

$db->setQuery($queryInsert)->execute();

Mais alors j'ai eu une erreur:

1136 Le nombre de colonnes ne correspond pas au nombre de valeurs à la ligne 1

bien que ce soient les mêmes colonnes dans les deux tableaux.

3
Midhat

Je pense que @Lodder a raison. Vous devez définir la première requête, puis l'exécuter également. Après la ligne ...

$db->setQuery($querySelect); ... ajoute également un ...

$db->execute($querySelect);

... puis continuez comme suggéré par Lodder. :-)

0
Jim Dee

Il y a quelques problèmes avec votre clause select et where

  • Si vous souhaitez sélectionner plusieurs colonnes, vous devez définir les colonnes sous forme de tableau.
  • Vous n'avez pas besoin d'insérer le nom de la table dans la clause where.
  • Dans la clause select, vous ne semblez pas définir les résultats pour les insérer

Essayez ce code mis à jour:

$querySelect = $db->getQuery(true);
$querySelect->select($db->qn(array('link_id', 'link_name', 'user_id')));
$querySelect->from($db->qn('#__mt_links'));
$querySelect->where($db->qn('link_id') . ' = ' . $db->q(3));
$db->setQuery($querySelect);

$results = $db->loadRowList();

$results est maintenant la variable qui contient vos résultats. Il peut contenir plus d'une ligne de résultats, vous devrez donc utiliser une boucle foreach lors de l'insertion des données.

Consultez la documentation pour savoir comment effectuer des requêtes dans la base de données: https://docs.joomla.org/Special:MyLanguage/Inserting,_Updating_and_Removing_data_using_JDatabase

1
Lodder

Vous ne devenez pas fou. MySQL et Joomla vous permettent de INSERT lignes d'une requête SELECT dans une seule transaction. J'ai testé les éléments suivants pour réussir sur mon hôte local, mais si vous ne me croyez pas, voyez ce que Nagarjun a à dire . Faire deux appels de base de données distincts à SELECT puis à INSERT manque une belle fonctionnalité de MySQL.

Voici votre hiccup de syntaxe solitaire:

$queryInsert->columns($db->quoteName(array('link_id, link_name, user_id')));

Cela signifie que vous voulez insérer les 3 colonnes de données dans une seule colonne de 27 caractères appelée:

`link_id, link_name, user_id`

Pourquoi donc? Vous avez simplement manqué les guillemets intérieurs et produit un tableau à 1 élément. Cela aurait été facile à négliger, puisque vous avez probablement copié-collé à partir de votre clause SELECT. Cela devrait être écrit comme ceci:

$queryInsert->columns($db->quoteName(array('link_id', 'link_name', 'user_id')));

Je suggérerai d'autres modifications infusées avec mes préférences personnelles:

  • Vous pouvez chaîner vos méthodes de requête à partir de la méthode getQuery() et éviter de ressaisir $queryWord Sur chaque ligne.
  • Votre méthode select() n'est pas besoin pour recevoir un tableau de colonnes (bien sûr, il peut). Dans votre cas, une chaîne séparée par des virgules contenant les trois noms de colonne est parfaitement valide/correcte.
  • qn() (quoteName() tel que vous l'utilisez) n'est en réalité nécessaire pour aucune des tables ou colonnes que vous avez mentionnées car il s'agit de mots entiers et non de "mots réservés".
  • Lorsque vous souhaitez sécuriser une valeur entière dynamique dans votre requête, vous pouvez simplement écrire (int) Avant de la convertir en entier. Si vous utilisez des nombres statiques/codés en dur, vous pouvez les écrire sans guillemets. Si vous utilisez des chaînes statiques/codées en dur, vous pouvez les envelopper manuellement entre guillemets simples.
  • Dans votre projet, si vous utilisez des variables/données fournies par l'utilisateur comme valeurs dans votre clause WHERE, vous devez appeler q() (ou quote()) de votre variables pour des raisons de sécurité.
  • Lorsque votre code est en direct/public, n’affichez jamais la chaîne de requête rendue ou le message d’erreur exact.
  • Un bloc try {} catch {} Est un moyen propre de gérer les erreurs pouvant survenir lors de l'interrogation.

Mon code suggéré:

$db = JFactory::getDBO();
    try {
        $querySelect = $db->getQuery(true)
                          ->select('link_id, link_name, user_id')
                          ->from('#__mt_links')
                          ->where('link_id = 3');

        $queryInsert = $db->getQuery(true)
                          ->insert('#__hikers')
                          ->columns(array('link_id', 'link_name', 'user_id'))
                          ->values($querySelect);

        echo $queryInsert->dump();
        $db->setQuery($queryInsert);
        $db->execute();
        echo "<div>Affected Rows: {$db->getAffectedRows()}</div>";
    } catch (Exception $e) {
        echo "<div>Error: {$e->getMessage()}</div>";
    }

Requête rendue (de ->dump()):

INSERT INTO eio3k_hikers
(link_id,link_name,user_id)
(
SELECT link_id, link_name, user_id
FROM eio3k_mt_links
WHERE link_id = 3)
0
mickmackusa