C#連接SQL-Server數據庫超詳細講解以及防SQL注入

C#連接SQL Server數據庫完整指南,整合了ADO.NET原生連接與Entity Framework Core兩種實現方式。

這篇文件詳細介紹C#代碼連接

數據庫的通用操作
數據庫鏈接功能 數據庫的增刪改查操作

? 1 配置全局數據庫鏈接字符串 App.config
2 獲取數據庫鏈接字符串

先在App.config配置連接字符串

<connectionStrings>
//name 自定義名稱 ?服務器名稱Server=ip地址 端口號;數據庫名稱 賬號-密碼
<add name="c1" connectionString="Server=.,1433;DataBase=SMDB;Uid=sa;Pwd=123456"/>
</connectionStrings>

server=.:指定服務器名稱為?.(自己計算機),表示數據庫服務器位于本地計算機上。.用于指代本地主機。

database=SMDB:指定要連接的數據庫名稱為?SMDB。這意味著連接成功后,將在?SMDB數據庫上執行數據庫操作。

uid=sa:指定用戶身份驗證使用的用戶名為?sasa?是 SQL Server 中的系統管理員賬戶。

pwd=123456:指定用戶身份驗證使用的密碼為?123456

? ?//獲取
public static readonly string connstring = ConfigurationManager.ConnectionStrings["c1"].ToString();

注:也可以在c#創建字符串來設置連接字符串在進行獲取

?* 執行sql命令幾個方法
* 1 cmd.ExCuteNonQuery 添加數據(insert into) 修改數據update 刪除數據delete
* 2 cmd.ExcuteScalar ? select count(*)
* 3 cmd.ExcuteReader ? 返回的是sqlDatareader 管道 需要使用while循環, select *
* 4 SqlDataAdapter da = new DataAdapter(cmd) ,select * 場景

展示案例

獲取單一結果的方法 列如 記錄個數等功能

//獲取單一結果的方法 列如 記錄個數等功能
public static object GrSigleResult(string sql)
{//1創建數據庫連接 SqlConnection=new SqlConnection(connstring);//2創建sql命令SqlCommand cmd=new SqlCommand(sql,conn)//打開連接執行命令try{conn.open();return cmd.ExecuteScalar();}catch(Exception){throw;}finally{conn.Close();}
}方法調用:// 獲取總人數public static int GetStudentCount(){string sql = "select count(*) from Students";return Convert.ToInt32(SQLHelper.GrtSigleResult(sql));}

執行增刪改查操作

//執行增刪改查操作
public static int Update(string sql)
{SqlConnection conn=new SqlConnection(connstring);SqlCommand cmd=new SqlCommand(sql,conn);try{conn.open();return cmd.ExecuteNonQuery();}catch(Exception){throw;}finally{conn.Close();}
}
方法調用:
public static bool ClockInSuccess(Attendance ad)
{string sql = "insert into Attendance(CarNo) Values('{0}')";sql = string.Format(sql,ad.CardNo);try{SQLHelper.Update(sql);return true;}catch (Exception){throw;}
}

SqlDataReader 存儲數據庫數據 獲取數據的所有記錄 要用while循環去讀

 public static SqlDataReader GetReader(string sql){SqlConnection conn = new SqlConnection(connstring);SqlCommand cmd = new SqlCommand(sql,conn);try{conn.Open();return cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);}catch (Exception){throw;}}
方法調用:1 返回的是對象類型public static Student GetStudentByCardNo(string cardNo){string sql = "select StudentId,StudentName,Gender,Birthday,StudentIdNo,PhoneNumber,ClassName,StudentAddress,CardNo,StuImage from Students ";sql += "inner join StudentClass on Students.ClassId = StudentClass.ClassId ";sql += "where CardNo = '{0}'";sql = string.Format(sql, cardNo);SqlDataReader r = SQLHelper.GetReader(sql);Student student = null;if (r.Read()){student = new Student(){StudentId = Convert.ToInt32(r["StudentId"]),StudentName = r["StudentName"].ToString(),Gender = r["Gender"].ToString(),BirthDay = Convert.ToDateTime(r["Birthday"]),StudentIdNo = r["StudentIdNo"].ToString(),PhoneNumber = r["PhoneNumber"].ToString(),ClassName = r["ClassName"].ToString(),StudentAddress = r["StudentAddress"].ToString(),CarNo = r["CardNo"].ToString(),StuImage = r["StuImage"] == null ? "" : r["StuImage"].ToString(),};}r.Close();return student;}
2返回list集合public static List<Student> GetScoreList(string cname){//全校成績string sql = "select Students.StudentId, StudentName,ClassName,Gender,CSharp,SqlserverDB from Students inner join ScoreList on Students.StudentId=ScoreList.StudentId inner join StudentClass on StudentClass.ClassId = Students.ClassId ";if (cname != null && cname.Length != 0){//按照班級查詢sql += "where ClassName = '" + cname + "'";}SqlDataReader r = SQLHelper.GetReader(sql);List<Student> list = new List<Student>();while (r.Read()){list.Add(new Student(){StudentId = Convert.ToInt32(r["StudentId"]),StudentName = r["StudentName"].ToString(),Gender = r["Gender"].ToString(),ClassName = r["ClassName"].ToString(),CSharp = Convert.ToInt32(r["CSharp"]),SqlserverDB = Convert.ToInt32(r["SqlserverDB"]),});}r.Close();return list;}

獲取所有的記錄 返回的是dataset數據類型 不要逐條給實體類字段進行賦值

public static DataSet GetDateSet(string sql)
{SqlConnection conn = new SqlConnection(connstring);SqlCommand cmd = new SqlCommand(sql,conn);DataSet ds=new DataSet();SqlDataAdapter da=new SqlDataAdapter(cmd)try{conn.Open();da.Fill(ds); // 把數據表數據填充在dataset集合中return ds;}catch (Exception){throw;}finally { conn.Close() ; } 
}
方法調用:/// <summary>/// 獲取所有成績的方法/// </summary>/// <returns></returns>public static DataSet GetAllScore(){string sql = "select Students.StudentId,StudentName,ClassName,Gender,PhoneNumber,CSharp,SqlserverDB from ScoreList inner join Students on Students.StudentId = ScoreList.StudentId inner join StudentClass on StudentClass.ClassId = Students.ClassId";return SQLHelper.GetDateSet(sql);}
Ui:private DataSet ds = null; // 放置所有的成績 數據集this.ds = ScoreService.GetAllScore();

獲取服務器時間

 public static DateTime GetDateTime(){return Convert.ToDateTime(GrtSigleResult("select getdate()"));}
方法調用:DateTime t0 = Convert.ToDateTime(SQLHelper.GetDateTime().ToShortDateString());public static bool UpdateDBFormExcelByShiWu(List<string> list){SqlConnection conn = new SqlConnection(connstring);SqlCommand cmd = new SqlCommand();cmd.Connection = conn;try{conn.Open();// 開啟事物cmd.Transaction = conn.BeginTransaction();// 把list里面指令添加事務中foreach (string s in list){cmd.CommandText = s;cmd.ExecuteNonQuery();}cmd.Transaction.Commit();return true;}catch (Exception ex){MessageBox.Show("添加失敗," + ex);return false;}finally{conn.Close();}}
方法調用:public static bool SaveDataToDB(List<Student> list){// 定義sql語句StringBuilder sql = new StringBuilder("insert into Students ");sql.Append("(StudentName,Gender,BirthDay,StudentIdNo,CardNo,Age,PhoneNumber,StudentAddress,ClassId) ");sql.Append("values ");sql.Append("('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}');");// 2 創建一個保存sql語句的集合List<string> sqlList = new List<string>();// 3 遍歷傳遞過來的學生集合對象int i = 1213;foreach (Student student in list){string s = string.Format(sql.ToString(), student.StudentName, student.Gender,student.BirthDay.ToString("yyyy-MM-dd"), student.StudentIdNo, student.CarNo+i, student.Age,student.PhoneNumber, student.StudentAddress, student.ClassId);sqlList.Add(s);i++;}return SQLHelper.UpdateDBFormExcelByShiWu(sqlList);}

SQL注入

當我們要在登錄賬號密碼時 不知道賬號密碼 可以字符串拼接 直接登錄 或一些其他刪除表等操作

比如用戶輸入: ' or 1=1 -- 就可以成功登錄了'是跟前面輸入的sql語句連接 or 1=1 當條件成立時 然后就可以成功登錄 --是省略后面的 甚至可以執行刪庫的操作: '; drop database xxxx

防止sql注入的方法就是避免直接將用戶輸入的內容拼接到sql語句中

使用帶參數的sql語句執行數據庫操作就可以避免sql注入

使用帶參數的sql語句不需要關注sql語句帶引號的問題

在sql語句中 使用@xxx 定義sql參數

案列:

// 2、在SqlCommand對象中為sql參數賦值// 添加參數的方法1(推薦)// cmd.Parameters.AddWithValue("@abc", textBox1.Text);           // 添加一個參數,并為參數賦值// cmd.Parameters.AddWithValue("@efg", textBox2.Text);// 添加參數的方法2//cmd.Parameters.Add("@abc", SqlDbType.VarChar);      // 添加一個參數,并指定參數的類型//cmd.Parameters["@abc"].Value = textBox1.Text;       // 為@abc參數賦值//cmd.Parameters.Add("@efg", SqlDbType.VarChar);//cmd.Parameters["@efg"].Value = textBox2.Text;// 添加參數的方法3//cmd.Parameters.Add(new SqlParameter("@abc", textBox1.Text));//cmd.Parameters.Add(new SqlParameter("@efg", textBox2.Text));// 添加參數的方法4(推薦)SqlParameter[] parameters = new SqlParameter[]{new SqlParameter("@abc", textBox1.Text),new SqlParameter("@efg", textBox2.Text)};cmd.Parameters.AddRange(parameters);封裝幾個類的方法/// <summary>/// 執行增刪改操作/// </summary>/// <param name="sql">要執行的sql語句</param>/// <param name="parameter">傳遞的sql參數</param>/// <returns></returns>public static int Update(string sql, params SqlParameter[] parameter){SqlCommand cmd = new SqlCommand(sql, conn);cmd.Parameters.AddRange(parameter);return cmd.ExecuteNonQuery();}/// <summary>/// 執行查詢操作/// </summary>/// <param name="sql">要執行的sql語句</param>/// <param name="parameter">傳遞的sql參數</param>/// <returns></returns>public static SqlDataReader GetData(string sql, params SqlParameter[] parameter){SqlCommand cmd = new SqlCommand(sql, conn);cmd.Parameters.AddRange(parameter);return cmd.ExecuteReader();}/// <summary>/// 執行單行單列的查詢操作/// </summary>/// <param name="sql">要執行的sql語句</param>/// <param name="parameter">傳遞的sql參數</param>/// <returns></returns>public static object GetObject(string sql, params SqlParameter[] parameter){SqlCommand cmd = new SqlCommand(sql, conn);cmd.Parameters.AddRange(parameter);return cmd.ExecuteScalar();}

下一節講EF(Entity Framework)?不需要寫連接字符串 因為在寫字符串也很難查找報錯地方因為字符串寫錯問題 以及連接創建許多代碼 和查詢等還需要注意SQL防注入?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/94763.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/94763.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/94763.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Pico2?ICE FPGA 開發板:從開箱到跑通示例的全歷程

FPGA 和 MCU 結合的開發板不多&#xff0c;而 Pico2?ICE 則把小巧、靈活和易上手完美結合。搭載 RP2350 雙核 RISC-V MCU Lattice iCE40UP5K FPGA&#xff0c;配合官方 SDK&#xff0c;你可以一步步跑通各種示例&#xff0c;從 LED 到 VGA&#xff0c;再到 MCU 與 FPGA 協作應…

Java圖形圖像處理【Swing圖像拖拽】【五】

Java圖形圖像處理【Swing圖像拖拽】 18.3.3 Swing圖像對象拖拽功能 18.3.3 Swing圖像對象拖拽功能 上文討論的是java.awt.dnd包中提供的拖拽API接口&#xff0c;也可稱之為AWT組件的拖拽功能。下面我們要討論的是Swing框架的拖拽功能&#xff1a;Swing組件也提供了對拖拽功能的…

狀態模式與幾個經典的C++例子

1. 狀態模式定義與核心思想 狀態模式解決的是當控制一個對象狀態轉換的條件表達式過于復雜時的情況。通過將狀態的判斷邏輯轉移到表示不同狀態的一系列類中,可以把復雜的判斷邏輯簡化。 核心思想: 狀態抽象:將對象的每個狀態都封裝到一個獨立的類中。 委托代替條件判斷:…

SyncBackPro 備份及同步軟件中的腳本功能簡介

腳本提供了一種靈活而簡單的方法來自動執行任務和擴展應用程序的功能。腳本是一個小程序&#xff0c;能夠自定義和控制備份作業。例如&#xff0c;用戶可以編寫腳本來復制、重命名或刪除特定文件、自定義用戶界面或更改配置文件設置。SyncBackPro 的腳本功能類似于 Microsoft O…

部署2.516.2版本的jenkins,同時適配jdk8

&#x1f4cc; 前言 在企業級開發中&#xff0c;我們常常面臨 新老項目并存 的復雜局面&#xff1a; 老項目基于 JDK 8 開發&#xff0c;短期內無法升級&#xff1b; 新項目采用 JDK 17&#xff08;LTS&#xff09;甚至更高版本&#xff1b; 而作為 CI/CD 核心的 Jenkins&#…

Autodesk Maya 2026.2 全新功能詳解:MotionMaker AI 動畫、LookdevX 材質增強、USD 工作流優化

軟件介紹 Autodesk Maya 2026.2是一款專業的3D計算機圖形軟件&#xff0c;它為數字內容創作者提供了豐富的工具集&#xff0c;以實現高質量的建模、動畫、模擬和渲染。該版本帶來了多項性能優化和工作流程改進&#xff0c;特別是針對生成式動畫工具MotionMaker進行了重大升級&…

STM32之DMA詳解

一、DMA 1. DMA的引入 在嵌入式系統或計算機系統中&#xff0c;數據的傳輸和處理是非常重要的操作。以下通過一個簡單的示例來展示傳統數據操作方式與 DMA 引入的必要性&#xff1a; int a 10; int b 20;a b;上述代碼包含了變量定義、初始化以及變量數據賦值操作。在傳統…

鏈表有環找入口節點原理

環形鏈表入口檢測算法數學解釋 數學原理假設定義: 鏈表頭到環入口的距離為 a環入口到相遇點的距離為 b相遇點到環入口的距離為 c環的長度為 b c第一次相遇時: 慢指針走了 s a b 步快指針走了 f a b n(b c) 步&#xff0c;其中 n 是快指針在環內轉的圈數由于快指針速度是…

Java 基本類型與包裝類詳解

Java 基本類型與包裝類詳解 在 Java 開發中&#xff0c;理解 基本數據類型與包裝類、字符串處理、以及高精度計算類是非常核心的能力。這不僅關系到程序性能&#xff0c;還影響代碼的正確性和可維護性。本文將詳細講解這些知識點&#xff0c;并給出常見的使用技巧和陷阱。 1?…

CRYPT32!CryptMsgUpdate函數分析之CRYPT32!PkiAsn1Decode函數的作用是得到pci

第一部分&#xff1a; CryptMsgUpdate( #endifIN HCRYPTMSG hCryptMsg,IN const BYTE *pbData,IN DWORD cbData,IN BOOL fFinal) {ContentInfo *pci NULL;if ((PHASE_FIRST_FINAL pcmi->dwPhase) &&(0 pcmi->dwMsgType)) {if (0 …

華為交換機S5700設置acl

1.、配置ACL1.1、定義允許的ACL規則[sw1]acl number 3001[sw1-acl-adv-3001]rule permit ip source 192.168.20.0 0.0.0.255 destination 192.168.40.1 0[sw1-acl-adv-3001]rule permit ip source 192.168.30.0 0.0.0.255 destination 192.168.40.1 01.2、定義禁止的ACL規則[sw…

在使用spring ai進行llm處理的rag的時候,選擇milvus還是neo4j呢?

在使用spring ai進行llm處理的rag的時候&#xff0c;選擇milvus還是neo4j呢&#xff1f; 對于Spring AI中的RAG&#xff08;Retrieval-Augmented Generation&#xff09;應用&#xff0c;選擇Milvus還是Neo4j&#xff0c;主要取決于你的數據類型以及RAG流程中對數據檢索的側重點…

計算機視覺與深度學習 | 視覺里程計技術全景解析:從原理到前沿應用

視覺里程計技術全景解析:從原理到前沿應用 一、定義與核心價值 二、技術原理與分類體系 2.1 基本工作流程 2.2 主流技術路線對比 2.3 算法范式演進 三、典型應用場景 3.1 地面移動機器人 3.2 自動駕駛領域 3.3 深空探測 3.4 增強現實 四、核心技術挑戰與突破路徑 4.1 主要技術…

Wireshark和USRP捕獲同一信號波形差異原因

一、波形差異 在前面的博客中我對比繪制了同一信號的Wireshark和USRP兩種波形&#xff1a; 可以看出波形差別還是挺大的&#xff0c;尤其是在信號分布間隔方面。 我猜想Wireshark的一條數據包在物理上并不是連續的&#xff1a; 而是分組發送&#xff0c;但在Wireshark中合并在…

Python-GEE遙感云大數據分析、可視化與Satellite Embedding應用

隨著航空、航天、近地空間遙感平臺的持續發展&#xff0c;遙感技術近年來取得顯著進步。遙感數據的空間、時間、光譜分辨率及數據量均大幅提升&#xff0c;呈現出大數據特征。2025年7月&#xff0c;Google DeepMind發布了革命性的AlphaEarth Foundations模型及Satellite Embedd…

Python常見設計模式2: 結構型模式

文章目錄適配器模式橋接模式組合模式外觀模式代理模式適配器模式 將一個類的接口轉換成客戶希望的另一個接口。適配器模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。兩種實現方式&#xff1a; 類適配器&#xff1a;使用多繼承對象適配器&#xff1a;使用組合…

HDMI2.1 8K驗證平臺

本文推薦其中一個平臺ZCU106HDMI2.1 FMC Card 一、ZCU106主要特性與優勢 經過優化&#xff0c;可采用 Zynq Ultrascale MPSoC 快速進行應用原型設計集成型視頻編解碼器單元支持 H.264/H.265HDMI 視頻輸入輸出PCIe 端點 Gen3x4、USB3、DisplayPort 和 SATADDR4 SODIMM – 64 位…

R語言使用隨機森林對數據進行插補

數據插補的目的是為了恢復數據的完整性&#xff0c;以便后續的數據分析和挖掘工作能夠順利進行。插補方法的選擇取決于數據的特點和缺失模式。常見的插補方法包括均值插補、回歸插補、多重插補等。均值插補簡單易行&#xff0c;但可能會改變數據分布&#xff1b;回歸插補考慮了…

論文閱讀:ICLR 2024 GAIA: A Benchmark for General AI Assistants

https://arxiv.org/pdf/2311.12983 https://www.doubao.com/chat/18484357054754562 GAIA: A Benchmark for General AI Assistants GAIA&#xff1a;通用人工智能助手基準測試 該論文介紹了GAIA&#xff08;General AI Assistants&#xff09;基準測試&#xff0c;這是一…

【Cmake】靜態庫(編譯-鏈接-引用)相關函數

目錄 一.file 1.1.示例一 1.2.示例二 1.2.1.GLOB 1.2.2.GLOB_RECURSE 1.3.示例三 1.3.1.GLOB 1.3.2.GLOB_RECURSE 1.4.file(GLOB)的缺點 二.add_library 示例 1&#xff1a;創建一個簡單的靜態庫 示例 2&#xff1a;創建一個簡單的共享庫&#xff08;動態庫&#x…