You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio连接MSSQL成功但无法存储注册数据求助

问题

我是一名正在学习SQL的学生,通过YouTube教程实现Android Studio与MSSQL服务器的连接,APP的TextView显示连接状态正常,但点击注册按钮后,注册数据无法写入MSSQL数据库的register表,表始终为空。以下是我的Register.java代码:

package com.example.login;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.DatePickerDialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.StrictMode;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;



import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Calendar;

public class Register extends AppCompatActivity {

    private static String ip = "192.168.1.5";
    private  static String port = "1433";
    private static String Classes = "net.sourceforge.jtds.jdbc.Driver";
    private static String db = "DB_SWEENEY_USERS";
    private static String un = "depota";
    private static String pass = "1234";
    Connection con;
    Statement stmt;
    private TextView txtView1;
    private EditText InputFirstName;
    private EditText InputLastName;
    private EditText InputPassword;
    private EditText InputEmail;
    private static final String TAG = "Register";
    private TextView txtViewPickDate;
    private DatePickerDialog.OnDateSetListener mDateSetListener;
    public static final String PERSON_NAME = "com.name.MESSAGE";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register2);
        RadioGroup rdGroup = findViewById(R.id.rdGroup);
        rdGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
            String gender;
                switch (i){
                    case R.id.maleBtn:
                        gender = "Male";
                        break;
                    case R.id.femaleBtn:
                        gender = "Female";
                        break;
                }
            }
        }); //CHOOSE MALE AND FEMALE

        txtViewPickDate = findViewById(R.id.txtViewPickDate);
        txtViewPickDate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Calendar cal = Calendar.getInstance();
                int year = cal.get(Calendar.YEAR);
                int month = cal.get(Calendar.MONTH);
                int day = cal.get(Calendar.DAY_OF_MONTH);

                DatePickerDialog dialog = new DatePickerDialog(Register.this, android.R.style.Theme_Holo_Light_Dialog_MinWidth, mDateSetListener,year,month,day);
                dialog.show();
            }
        });//DATE PICKER
        mDateSetListener = new DatePickerDialog.OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker datePicker, int year, int month, int day) {
                month = month +1;
                Log.d(TAG, "onDateSet:mm/dd/yyy: " + month + "/" + day + "/" + year);
                String date = month + "/" + day + "/" + year;
                txtViewPickDate.setText(date);
            }
        };//DISPLAY DATE PICKER

        InputFirstName = findViewById(R.id.InputFirstName);
        InputLastName = findViewById(R.id.InputLastName);
        InputPassword = findViewById(R.id.InputPassword);
        InputEmail = findViewById(R.id.InputEmail);
        EditText InputConfirmPassword = findViewById(R.id.InputConfirmPassword);
        txtView1 = findViewById(R.id.txtView1);
        Button regBtn = findViewById(R.id.regBtn);



        regBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                new Register.registerUser().execute("");


                /* String password = InputPassword.getText().toString();
                String confirm = InputConfirmPassword.getText().toString();
                if(TextUtils.isEmpty(password) || TextUtils.isEmpty(confirm)) {
                    Toast.makeText(Register.this, "Password field is empty!", Toast.LENGTH_SHORT).show();
                } else if(password.equals(confirm)) {
                    Intent intent = new Intent(Register.this, Main_Menu.class);
                    String personName = InputFirstName.getText().toString() + " " + InputLastName.getText().toString();
                    intent.putExtra(PERSON_NAME, personName);
                    startActivity(intent);
                } else {
                    Toast.makeText(Register.this, "Password don't match", Toast.LENGTH_SHORT).show();
                }*/
            }
        });

    }


    public class registerUser extends AsyncTask<String, String, String>{
        String z = "";
        Boolean isSuccess= false;

        @Override
        protected void onPreExecute() {
            txtView1.setText("Sending Data to Datbase");
        }
        @Override
        protected void onPostExecute(String s) {
            txtView1.setText("Registration Successful");
            InputFirstName.setText("");
            InputLastName.setText("");
            InputPassword.setText("");
            InputEmail.setText("");
        }

        @Override
        protected String doInBackground(String... strings) {
            try {
                 con = connectionClass(un.toString(), pass.toString(),db.toString(),ip.toString());
                 if (con==null){
                     z = "ERROR DEPOTA NA ANO NI MAN";
                 }else{
                     String sql = "INSERT INTO register (firstName,lastName,middleInitial,gender,bDate,uName,email,pass) VALUES ('"+InputFirstName.getText()+"','"+InputLastName.getText()+"','"+"NULL"+"','"+"NULL"+"','"+"NULL"+"','"+"NULL"+"','"+InputEmail.getText()+"','"+InputPassword.getText()+"')";
                     stmt = con.createStatement();
                     stmt.executeUpdate(sql);
                 }
            }catch (Exception e){
                    isSuccess = false;
                    z = e.getMessage();
            }
            return z;
        }
    }

    @SuppressLint("NewApi")
    public Connection connectionClass(String user, String password, String database, String server){
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
        Connection connection = null;
        String connectionURL = null;
        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            connectionURL = "jdbc:jtds:sqlserver://" +server+"/" +database+";user=" + user+";password=" +password + ";";
            connection = DriverManager.getConnection(connectionURL);

        } catch (Exception e) {
            Log.e("SQL Connection Error", e.getMessage());
        }
        return connection;
    }
}

排查与修复方案

1. 核心SQL语句错误

  • 未获取输入文本:原代码直接拼接InputFirstName.getText(),未调用toString(),实际插入的是EditText对象的内存地址而非用户输入内容,需改为InputFirstName.getText().toString().trim()。
  • 错误处理NULL值:原代码将NULL用单引号包裹,变成字符串'NULL',而非SQL的空值。若数据库字段不允许该字符串格式,会导致插入失败,需用PreparedStatement的setNull()方法处理空值。

2. 错误反馈缺失

原onPostExecute方法不管插入成功与否都显示“Registration Successful”,无法获取实际错误信息。修改后根据isSuccess状态显示结果,并通过Toast提示错误详情,方便排查问题。

3. 未收集完整用户数据

原代码未保存性别和出生日期的选择结果,导致这两个字段无法插入数据库。新增selectedGender和selectedBirthDate变量存储用户选择值,并在SQL中传入。

4. 连接字符串遗漏端口

原代码定义了port变量但未使用,需将连接地址改为ip + ":" + port,确保连接到正确的数据库端口。

5. 避免SQL注入风险

使用PreparedStatement替代Statement,既可以避免SQL注入,也能简化参数拼接逻辑,减少语法错误。

修复后的关键代码片段

public class Register extends AppCompatActivity {
    // 新增变量保存性别和出生日期
    private String selectedGender = null;
    private String selectedBirthDate = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register2);
        
        // 修改RadioGroup监听,保存性别选择
        RadioGroup rdGroup = findViewById(R.id.rdGroup);
        rdGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
                switch (i){
                    case R.id.maleBtn:
                        selectedGender = "Male";
                        break;
                    case R.id.femaleBtn:
                        selectedGender = "Female";
                        break;
                    default:
                        selectedGender = null;
                }
            }
        });

        // 修改日期选择监听,保存出生日期
        mDateSetListener = new DatePickerDialog.OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker datePicker, int year, int month, int day) {
                month = month +1;
                Log.d(TAG, "onDateSet:mm/dd/yyy: " + month + "/" + day + "/" + year);
                selectedBirthDate = month + "/" + day + "/" + year;
                txtViewPickDate.setText(selectedBirthDate);
            }
        };

        // 注册按钮点击事件,新增必填字段校验
        regBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (TextUtils.isEmpty(InputFirstName.getText().toString()) ||
                    TextUtils.isEmpty(InputEmail.getText().toString()) ||
                    TextUtils.isEmpty(InputPassword.getText().toString())) {
                    Toast.makeText(Register.this, "必填字段不能为空", Toast.LENGTH_SHORT).show();
                    return;
                }
                new registerUser().execute("");
            }
        });
    }

    public class registerUser extends AsyncTask<String, String, String> {
        String z = "";
        Boolean isSuccess = false;

        @Override
        protected void onPostExecute(String s) {
            if (isSuccess) {
                txtView1.setText("Registration Successful");
                InputFirstName.setText("");
                InputLastName.setText("");
                InputPassword.setText("");
                InputEmail.setText("");
                txtViewPickDate.setText("");
                selectedGender = null;
            } else {
                txtView1.setText("Registration Failed: " + s);
                Toast.makeText(Register.this, "错误信息: " + s, Toast.LENGTH_LONG).show();
            }
        }

        @Override
        protected String doInBackground(String... strings) {
            try {
                // 加入端口号
                con = connectionClass(un, pass, db, ip + ":" + port);
                if (con == null) {
                    z = "无法连接到数据库";
                } else {
                    // 使用PreparedStatement插入数据
                    String sql = "INSERT INTO register (firstName, lastName, middleInitial, gender, bDate, uName, email, pass) " +
                                "VALUES (?, ?, NULL, ?, ?, NULL, ?, ?)";
                    PreparedStatement pstmt = con.prepareStatement(sql);
                    pstmt.setString(1, InputFirstName.getText().toString().trim());
                    pstmt.setString(2, InputLastName.getText().toString().trim());
                    // 处理性别空值
                    if (selectedGender != null) {
                        pstmt.setString(3, selectedGender);
                    } else {
                        pstmt.setNull(3, java.sql.Types.VARCHAR);
                    }
                    // 处理出生日期空值
                    if (selectedBirthDate != null) {
                        pstmt.setString(4, selectedBirthDate);
                    } else {
                        pstmt.setNull(4, java.sql.Types.VARCHAR);
                    }
                    pstmt.setString(5, InputEmail.getText().toString().trim());
                    pstmt.setString(6, InputPassword.getText().toString().trim());

                    int affectedRows = pstmt.executeUpdate();
                    if (affectedRows > 0) {
                        isSuccess = true;
                        z = "数据插入成功";
                    } else {
                        z = "未插入任何数据";
                    }
                    pstmt.close();
                    con.close();
                }
            } catch (Exception e) {
                isSuccess = false;
                z = e.getMessage();
                Log.e("Register Error", z);
            }
            return z;
        }
    }
}

额外检查项

  1. 确认MSSQL用户depota拥有register表的INSERT权限。
  2. 检查register表的字段类型与插入数据是否匹配(例如email字段长度是否足够,bDate字段是否支持字符串格式日期)。
  3. 查看MSSQL的错误日志,确认是否有插入操作的报错记录。

内容的提问来源于stack exchange,提问作者seyan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 07:54:53