Android& SQL - SQL查询不断更新错误的列

时间:2017-02-28 21:27:36

标签: java php android mysql wamp

问题
我一直在尝试使用 WAMP 在我的本地数据库和 MySQL 数据库服务器之间创建同步。此同步以 JSON 格式从我的数据库发送所有数据,并根据是否存在重复键来插入或更新它。然后,我从 MySQL 数据库中检索所有数据,清除应用程序创建的本地数据库并将所有新数据存储在其中。但是,这并不像我希望的那样,因为我发送到数据库服务器的数据会一直覆盖具有不同密钥的列。

单词示例
我有一个团队,两个数据库之间的密钥 5024 已同步。我使用密钥 3756 将新的 Team 添加到我的本地数据库,然后尝试将本地数据库与MySQL数据库同步。但是,同步不按计划进行,因为大多数情况下数据库不会插入带有键的新列。它会更新一个具有完全 DIFFERENT 键的行,并将数据发送给它。

额外信息
有时,同步确实按计划运行,并添加了一个包含已发送信息的新列,但此数据会在下次同步时被覆盖

示例JSON对象 {"TeamNumber":5024,"TeamName":"Ramferno","AutoFuelLow":"yes","AutoFuelHigh":"no","AutoFuelPoints":15,"AutoRotorEngaged":"no","TeleFuelLow":"yes","TeleFuelHigh":"no","TeleFuelPoints":20,"TeleRotorEngaged":"yes","Hang":"yes","PlayStyle":"Defensive"}

WAMP服务器服务&语言
MySQL:5.7.14
PHP:5.6.25
Apache:2.4.23
PHPMyAdmin:4.6.6

如何传送数据
我的android类从本地SQLite数据库中检索数据,将其存储在Cursor对象中。然后,它将遍历Cursor中的每一行数据并将其传输到JSONObject,然后通过BufferedWriter将其发送到数据库服务器,该$_POST可以访问输出流。因为有连接(已在每次同步时进行)。数据库上的PHP脚本(连接到android类中)获取所有信息,通过INSERT INTO ON DUPLICATE KEY解码,然后使用发送JSONArray SQL 查询到数据库服务器包含收到的数据。

我尝试过的事情

  • 添加延迟
  • 使用package org.ramferno.ramfernoscouting2017.sql; import android.app.ProgressDialog; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.os.AsyncTask; import android.support.v4.app.Fragment; import android.util.Log; import android.widget.Toast; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.ramferno.ramfernoscouting2017.LaunchActivity; import org.ramferno.ramfernoscouting2017.fragments.ScoutFragment; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.SocketTimeoutException; import java.net.URL; import java.net.URLEncoder; import java.util.Iterator; // Start of DatabaseTransfer @SuppressWarnings({"FieldCanBeLocal", "ConstantConditions"}) public class DatabaseTransfer extends AsyncTask<String, String, String> { // Declare object references private Context context; private ProgressDialog pDialog; private Fragment fragment; // Declare variables private String urlAddress; /** * Constructor for the class * @param context is the application context * @param urlAddress is a url address with an accessible MySQL database */ public DatabaseTransfer(Context context, String urlAddress, Fragment fragment) { this.context = context; this.urlAddress = urlAddress; this.fragment = fragment; } //End of constructor @Override protected void onPreExecute() { super.onPreExecute(); // Display dialog pDialog = new ProgressDialog(context); pDialog.setMessage("Syncing Data ..."); pDialog.setIndeterminate(false); pDialog.setCancelable(true); pDialog.show(); } // End of method @Override protected String doInBackground(String... args) { sendData(); getAndStoreData(); return "true"; } // End of method @Override protected void onPostExecute(String s) { super.onPostExecute(s); ScoutFragment scoutFragment = (ScoutFragment) fragment; scoutFragment.refreshListView(); // Make toast which indicates if response was successful Toast.makeText(context, s, Toast.LENGTH_LONG).show(); // Dismiss dialog pDialog.dismiss(); } // End of method /** * Attempts a GET connection to a database server * @return a connection object */ private HttpURLConnection attemptGetConnection() { try { // Declare and instantiate URL object URL url = new URL("http://" + urlAddress + "/ramfernoscout/database/retrieve.php"); // Open connection HttpURLConnection con = (HttpURLConnection) url.openConnection(); // Set request properties con.setRequestMethod("GET"); con.setConnectTimeout(20000); con.setReadTimeout(20000); con.setDoInput(true); // Return connection return con; } catch (SocketTimeoutException errTO) { Log.e("ERROR TO", errTO.getMessage()); return null; } catch (MalformedURLException errURL) { Log.e("ERROR URL", errURL.getMessage()); return null; } catch (IOException errIO) { errIO.printStackTrace(); return null; } // End of try statement } // End of method /** * Attempts a POST connection to a database server * @return a connection object */ private HttpURLConnection attemptPostConnection() { try { URL url = new URL("http://" + urlAddress + "/ramfernoscout/database/updateadd.php"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); // Set request properties con.setRequestMethod("POST"); con.setConnectTimeout(20000); con.setReadTimeout(20000); con.setDoInput(true); con.setDoOutput(true); // Return connection return con; } catch (SocketTimeoutException errTO) { Log.e("ERROR TO", errTO.getMessage()); return null; } catch (MalformedURLException errURL) { Log.e("ERROR URL", errURL.getMessage()); return null; } catch (IOException errIO) { errIO.printStackTrace(); return null; } // End of try statement } // End of method /** * Sends all data inside local database to database server * @return a response code as a string */ @SuppressWarnings("static-access") private String sendData() { //Connect the server HttpURLConnection con = attemptPostConnection(); //Check if connection was successful if(con == null) { return null; } //End of if statement // Attempt to insert data into the database try { // Declare and instantiate objects OutputStream os = con.getOutputStream(); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os,"UTF-8")); final Cursor cursor = LaunchActivity.dbHelper.getData(LaunchActivity.dbHelper .getReadableDatabase(), "*", 0); cursor.moveToFirst(); // Iterate through the entire cursor and add data to database for (int i = 0; i < cursor.getCount(); i++) { // Write data to database server bw.write(packData(cursor)); cursor.moveToNext(); } // End of for loop // Close stream and writer bw.close(); os.close(); // Store response code in integer int responseCode = con.getResponseCode(); // Check if data was successfully enter into the database if(responseCode == con.HTTP_OK) { // Declare and instantiate objects BufferedReader br = new BufferedReader(new InputStreamReader (con.getInputStream())); StringBuilder response = new StringBuilder(); String line; // Get full response while ((line=br.readLine()) != null) { response.append(line); } // End of while statement // Close reader and return response br.close(); return response.toString(); } // End of if statement } catch (IOException errIO) { Log.e("ERROR IO", errIO.getMessage()); errIO.printStackTrace(); } //End of try statement return null; } // End of method /** * Packs database information into a string which can be sent to the database server * @param cursor is a Cursor object containing data * @return a string */ private String packData(Cursor cursor) { //Declare and instantiate objects JSONObject jo = new JSONObject(); StringBuilder packedData = new StringBuilder(); // Attempt to send data to the server via JSON try { // Put all data in a json object jo.put(DatabaseContract.ScoutTable.TEAM_NUMBER, cursor.getInt(cursor .getColumnIndexOrThrow(DatabaseContract.ScoutTable.TEAM_NUMBER))); jo.put(DatabaseContract.ScoutTable.TEAM_NAME, cursor.getString(cursor .getColumnIndexOrThrow(DatabaseContract.ScoutTable.TEAM_NAME))); jo.put(DatabaseContract.ScoutTable.AUTO_FUEL_LOW, cursor.getString(cursor .getColumnIndexOrThrow(DatabaseContract.ScoutTable.AUTO_FUEL_LOW))); jo.put(DatabaseContract.ScoutTable.AUTO_FUEL_HIGH, cursor.getString(cursor .getColumnIndexOrThrow(DatabaseContract.ScoutTable.AUTO_FUEL_HIGH))); jo.put(DatabaseContract.ScoutTable.AUTO_FUEL_POINTS, cursor.getInt(cursor .getColumnIndexOrThrow(DatabaseContract.ScoutTable.AUTO_FUEL_POINTS))); jo.put(DatabaseContract.ScoutTable.AUTO_ROTOR_ENGAGED, cursor.getString(cursor .getColumnIndexOrThrow(DatabaseContract.ScoutTable.AUTO_ROTOR_ENGAGED))); jo.put(DatabaseContract.ScoutTable.TELE_FUEL_LOW, cursor.getString(cursor .getColumnIndexOrThrow(DatabaseContract.ScoutTable.TELE_FUEL_LOW))); jo.put(DatabaseContract.ScoutTable.TELE_FUEL_HIGH, cursor.getString(cursor .getColumnIndexOrThrow(DatabaseContract.ScoutTable.TELE_FUEL_HIGH))); jo.put(DatabaseContract.ScoutTable.TELE_FUEL_POINTS, cursor.getInt(cursor .getColumnIndexOrThrow(DatabaseContract.ScoutTable.TELE_FUEL_POINTS))); jo.put(DatabaseContract.ScoutTable.TELE_ROTOR_ENGAGED, cursor.getString(cursor .getColumnIndexOrThrow(DatabaseContract.ScoutTable.TELE_ROTOR_ENGAGED))); jo.put(DatabaseContract.ScoutTable.ENDGAME_HANG, cursor.getString(cursor .getColumnIndexOrThrow(DatabaseContract.ScoutTable.ENDGAME_HANG))); jo.put(DatabaseContract.ScoutTable.PLAY_STYLE, cursor.getString(cursor .getColumnIndexOrThrow(DatabaseContract.ScoutTable.PLAY_STYLE))); Log.e("Print JSON Object", jo.toString()); // Declare and instantiate objects Boolean firstValue = true; Iterator it = jo.keys(); // Organize data in JSON format do { // Go through each key and value in JSONObject String key = it.next().toString(); String value = jo.get(key).toString(); // Check if first value in the list if(firstValue) { firstValue = false; } else { packedData.append("&"); } // End of if statement // Append to string in order to create JSON format packedData.append(URLEncoder.encode(key,"UTF-8")); packedData.append("="); packedData.append(URLEncoder.encode(value,"UTF-8")); } while (it.hasNext()); // End of do statement // Return packed data in string format return packedData.toString(); } catch (JSONException errJSON) { // If occurs, log error Log.e("ERROR JSON", errJSON.getMessage()); } catch (UnsupportedEncodingException errUEE) { // If occurs, log error Log.e("ERROR UEE", errUEE.getMessage()); } // End of try statement // Return nothing return null; } // End of packData /** * Downloads data from the database server and stores it in local database */ private String getAndStoreData() { // Attempt connection to server HttpURLConnection con = attemptGetConnection(); // If no connection, return nothing if(con == null) { return "ERROR: Connection unsuccessful, please make sure you are properly connected " + "to the right IP address which has access to the database server"; } // End of if statement // Declare InputStream InputStream is = null; // Attempt to read the file of data try { // Declare and instantiate objects is = new BufferedInputStream(con.getInputStream()); BufferedReader br = new BufferedReader(new InputStreamReader(is)); StringBuilder response = new StringBuilder(); // Declare object references String line; String responseString = ""; // Read all lines of data until the end of the file is reached if(br != null) { while ((line = br.readLine()) != null) { responseString += line; } //End of while statement // Add string to string builder response.append(responseString); // Close reader br.close(); } else { throw new IOException(); } //End of if statement // Declare and instantiate objects JSONArray jsonArray = new JSONArray(response.toString()); JSONObject jsonObject; // Reset scout table LaunchActivity.dbHelper.onUpgrade(LaunchActivity.dbHelper.getWritableDatabase(), 0); // Iterate through JSON array and add each set to database for(int i = 0; i < jsonArray.length(); i++) { jsonObject = jsonArray.getJSONObject(i); // Store data in Content values ContentValues values = new ContentValues(); values.put(DatabaseContract.ScoutTable.TEAM_NUMBER, jsonObject.getInt(DatabaseContract.ScoutTable.TEAM_NUMBER)); values.put(DatabaseContract.ScoutTable.TEAM_NAME, jsonObject.getString(DatabaseContract.ScoutTable.TEAM_NAME)); values.put(DatabaseContract.ScoutTable.AUTO_FUEL_LOW, jsonObject.getString(DatabaseContract.ScoutTable.AUTO_FUEL_LOW)); values.put(DatabaseContract.ScoutTable.AUTO_FUEL_HIGH, jsonObject.getString(DatabaseContract.ScoutTable.AUTO_FUEL_HIGH)); values.put(DatabaseContract.ScoutTable.AUTO_FUEL_POINTS, jsonObject.getInt(DatabaseContract.ScoutTable.AUTO_FUEL_POINTS)); values.put(DatabaseContract.ScoutTable.AUTO_ROTOR_ENGAGED, jsonObject.getString(DatabaseContract.ScoutTable.AUTO_ROTOR_ENGAGED)); values.put(DatabaseContract.ScoutTable.TELE_FUEL_LOW, jsonObject.getString(DatabaseContract.ScoutTable.TELE_FUEL_LOW)); values.put(DatabaseContract.ScoutTable.TELE_FUEL_HIGH, jsonObject.getString(DatabaseContract.ScoutTable.TELE_FUEL_HIGH)); values.put(DatabaseContract.ScoutTable.TELE_FUEL_POINTS, jsonObject.getInt(DatabaseContract.ScoutTable.TELE_FUEL_POINTS)); values.put(DatabaseContract.ScoutTable.TELE_ROTOR_ENGAGED, jsonObject.getString(DatabaseContract.ScoutTable.TELE_ROTOR_ENGAGED)); values.put(DatabaseContract.ScoutTable.ENDGAME_HANG, jsonObject.getString(DatabaseContract.ScoutTable.ENDGAME_HANG)); values.put(DatabaseContract.ScoutTable.PLAY_STYLE, jsonObject.getString(DatabaseContract.ScoutTable.PLAY_STYLE)); // Add data to database LaunchActivity.dbHelper.insert(LaunchActivity.dbHelper.getWritableDatabase(), values, 0); } // End of for loop } catch (IOException errIO) { // If occurs, log error and return false Log.e("ERROR IO", errIO.getMessage()); return "ERROR"; } catch (JSONException errJSON) { // If occurs, log error and return false Log.e("ERROR JSON", errJSON.getMessage()); return "ERROR"; } finally { // Close input stream if(is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } // End of try statement } // End of if statement } // End of try statement // Return success message if no error occurs return "Sync successful!"; } // End of method } // End of class 只能写入数据库一次
  • 删除并重新添加表中的键作为主键或唯一

代码
DatabaseTransfer.java (从本地数据库发送数据的Android类)

<?php
/*
 * This script will add data into a database
 */

// Import the script that connects to the required database
require "init.php";

// Declare and initialize parameters (These parameters will have data entered into them by the android app)
$teamNumber = $_POST['TeamNumber'];
$teamName = $_POST['TeamName'];
$autoFuelLow = $_POST['AutoFuelLow'];
$autoFuelHigh = $_POST['AutoFuelHigh'];
$autoFuelPoints = $_POST['AutoFuelPoints'];
$autoRotorEngaged = $_POST['AutoRotorEngaged'];
$teleFuelLow = $_POST['TeleFuelLow'];
$teleFuelHigh = $_POST['TeleFuelHigh'];
$teleFuelPoints = $_POST['TeleFuelPoints'];
$teleRotorEngaged = $_POST['TeleRotorEngaged'];
$endgame = $_POST['Hang'];
$playStyle = $_POST['PlayStyle'];

// This query inserts data into the database
$sql_query = "INSERT INTO scoutdb (TeamNumber, TeamName, AutoFuelLow, AutoFuelHigh, AutoFuelPoints, AutoRotorEngaged, TeleFuelLow, TeleFuelHigh, TeleFuelPoints, TeleRotorEngaged, Hang, PlayStyle) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE TeamName=VALUES(TeamName), AutoFuelLow=VALUES(AutoFuelLow), AutoFuelHigh=VALUES(AutoFuelHigh), AutoFuelPoints=VALUES(AutoFuelPoints), AutoRotorEngaged=VALUES(AutoRotorEngaged), TeleFuelLow=VALUES(TeleFuelLow), TeleFuelHigh=VALUES(TeleFuelHigh), TeleFuelPoints=VALUES(TeleFuelPoints), TeleRotorEngaged=VALUES(TeleRotorEngaged), Hang=VALUES(Hang), PlayStyle=VALUES(PlayStyle);";

// Prepare the SQL statement
if(!($stmt = $con->prepare($sql_query))) {
    echo "Statement could no be prepared: (".$con->errno.") ".$con->error;
} // End of if statement

// Bind parameters to the statement
if(!($stmt->bind_param("isssisssisss", $teamNumber, $teamName, $autoFuelLow, $autoFuelHigh, $autoFuelPoints,
    $autoRotorEngaged, $teleFuelLow, $teleFuelHigh, $teleFuelPoints, $teleRotorEngaged, $endgame, $playStyle))) {
    // Display a message if an error occurs when binding
    echo "Data could not be binded: (".$stmt->errno.") ".$stmt->error;;
} // End of if statement

// Execute statement
if (!($stmt->execute())) {
    // Display a message if an error occurs when executing
    echo "Execute failed: (".$stmt->errno.") ".$stmt->error;
} // End of if statement
?>

updateadd.php (接收数据并向数据库发送查询的内容)

{% import salt.config %}
{% minion_opts = salt.config.minion_config('/etc/salt/minion') %}
{% print(minion_opts['id']) %}
{% if minion_opts['id'] == 'xyz.server': %}
-- run the logic here
..
..

表格结构

enter image description here

如果您需要任何其他文件,请告诉我们,谢谢!
更新:仍然无法弄清楚问题,我总是在数据覆盖之间切换回不应该或根本不更新

0 个答案:

没有答案