SQL Server笔记

数据库的层次结构

SQLServer>多个服务器>多个数据库>多个table

连接数据库错误

win+R>services.msc

修改表后不允许保存

设置Id自增

让创建时间默认为现在时间

默认值或绑定写getdate()

为表批量设置创建时间

如果之前表里创建时间有NULL,先全部写入创建时间。

UPDATE UserTable
SET CreateTime=GETDATE()
WHERE CreateTime IS NULL
ALTER TABLE UserTable
ALTER COLUMN CreateTime DATETIME NOT NULL

删除已存在的存储过程

DROP PROCEDURE IF EXISTS XXX;
IF EXISTS (SELECT * FROM sysobjects WHERE name='XXX' AND type='P')
    DROP PROCEDURE XXX
GO

type指定类型是存储过程。

增INSERT、删DELETE、改UPDATE、查SELECT

GO的意思

不是SQL语句,是SSMS专用的让SQL一段一段编译的。

SET NOCOUNT ON

让不再返回受影响的行数。

SELECT @@IDENTITY

获取你刚才插入数据,自动生成的 ID 号。

你数据库里一般都有一列:ID INT IDENTITY(1,1) PRIMARY KEY自增主键,插入数据时不用你填,数据库自动给数字。

@@IDENTITY 就是拿到刚才那条数据的 ID 是多少

设置存储过程执行到哪个数据库

在执行键左边选:

SELECT的作用

返回一张表。逗号分割输入它的列

char(n)、varchar和nvarchar

char(n):固定n个字节,没用完补空格。里面英文数字和中文字节数不一样。

var是长度可变的。

varchar:英文、数字1字节,汉字2字节。容易乱码。

nvarchar:各种语言一个字符都2字节。不容易乱码,多占空间。

sqlConnection.Open()错误

改成左边点开服务器资源管理器,连接成功后右下角拷贝连接字符串。

trust server certificate不支持

.NET Framework下这里不要有空格。

dataSet.Tables[0]是null

断点打太靠上了!!应该下面再写一行打断点。

Insert写字段名 → 可以只插部分字段 不写字段名 → 必须按顺序插全部字段

C#调用数据库的过程

建立SqlConnection>建立SqlCommand并和SqlConnection关联>

查询指令,建立SqlDataAdapter,和SqlCommand关联>建立DataSet,SqlDataAdapter.Fill填充数据>用Row和Column读取。

非查询指令,ExecuteNonQuery得到影响行数。

类的个数稍多,还可以。

编程语言调用数据库面对的情景

需要大量参数:连接字符串、表名、SQL语句或存储过程、SQL语句的参数(还包括参数名和参数值)。

而且需要参数的数量、类型不固定,select需要从0个(全查询)到任意多个条件,insert至少输入不能为Null的,如果想缺省还需要把参数名输入。

然后发现Select要返回数据表,增、删、改只返回影响的行数int,那么查封装一个函数,增删改封装一个。

然后因为要执行的SQL或存储过程极度灵活,应该封装一个输入指令的函数。那么还需要一些函数生成指令。

Entity

一个数据库表的一条数据在编程语言里对应的类。

从DataRow转换为Entity(基于反射、特性)

using System;
using System.Data;
using System.Reflection;

namespace LearnCSharp
{
    public class AccountEntity
    {
        [DBName("Id")]
        public int Id { get; set; }
        [DBName("Status")]
        public int Status {  get; set; }
        [DBName("UserName")]
        public string UserName { get; set; }
        [DBName("Password")]
        public string Password { get; set; }
        [DBName("Mobile")]
        public string Mobile {  get; set; }
        [DBName("Email")]
        public string Email { get; set; }
        [DBName("Money")]
        public int Money {  get; set; }
        [DBName("ChannelID")]
        public int ChannelID {  get; set; }
        [DBName("LastServerID")]
        public int LastServerID {  get; set; }
        [DBName("LastServerName")]
        public string LastServerName {  get; set; }
        [DBName("LastServerTime")]
        public DateTime LastServerTime { get; set; }
        [DBName("LastRoleID")]
        public int LastRoleID {  get; set; }
        [DBName("LastRoleName")]
        public string LastRoleName { get; set; }
        [DBName("LastRoleJobID")]
        public int LastRoleJobID {  get; set; }
        [DBName("CreateTime")]
        public DateTime CreateTime { get; set; }
        [DBName("UpdateTime")]
        public DateTime UpdateTime { get; set; }
        public void SetData(DataRow row)
        {
            Type type = typeof(AccountEntity);
            PropertyInfo[] propertyInfo=type.GetProperties();
            foreach (var property in propertyInfo)
            {
                DBNameAttribute attribute = property.GetCustomAttribute<DBNameAttribute>(false);
                if (attribute != null)
                {
                    string colName = attribute.Name;
                    if (row.Table.Columns.Contains(colName))
                    {
                        object value = row[colName];
                        if (value != DBNull.Value)
                        {
                            property.SetValue(this, ConvertValue(value, property.PropertyType));
                        }
                    }
                }
            }
        }
        object ConvertValue(object value, Type targetType)
        {
            if (value == null)
                return null;

            Type underlyingType = Nullable.GetUnderlyingType(targetType) ?? targetType;
            return Convert.ChangeType(value, underlyingType);
        }
    }
}

join连表查询

左连:=左边的表都查出来,如果右边的表没有记录就显示NULL,也查出来。

select * from UserT
left join
UserScoreT
on UserT.UserName=UserSceneT.UserName

右连:=右边没有匹配的就不显示。

SQL Server身份验证登录

打开Services.msc>SQL Server重启。

由表得到创建它的SQL语句

ParameterDirection.Output和ParameterDirection.ReturnValue什么区别

Output

  • 可以多个
  • 类型任意(int、string、datetime 都行)
  • 必须在存储过程声明 OUTPUT

ReturnValue

只能返回一个 int 数字,相当于存储过程的 exit code

C#的

sqlParameter.Direction = ParameterDirection.Output;

对应

@Id         INT OUTPUT,

sqlParameter.Direction = ParameterDirection.ReturnValue;

在sql那边不写在参数列表,而是RETURN。

存储过程返回成功但是查询不到

用SQL执行存储过程没问题。

public MFReturnValue<int> Register(string username, string password,string channelId)
{
    var ret = new MFReturnValue<int>();
    using(SqlConnection connection=new SqlConnection(DBConn.UsersDB))
    {
        connection.Open();
        SqlTransaction transaction = connection.BeginTransaction();
        List<AccountEntity> accountEntities =
        GetListWithTran(TableName, "Id", $"UserName='{username}'", trans: transaction);
        if (accountEntities == null|| accountEntities.Count==0)
        {//用户名不存在
            var entity=new AccountEntity();
            entity.UserName = username;
            entity.Password =MyTools.MD5(password);
            entity.ChannelID =short.Parse( channelId);
            entity.LastServerTime = DateTime.Now;
            entity.CreateTime = DateTime.Now;
            entity.UpdateTime = DateTime.Now;
            MFReturnValue<object>ret1= Create(transaction, entity);
            if (ret1.HasError)
            {
                ret.HasError = true;
                ret.Message = ret1.Message;
                transaction.Rollback();
                System.Diagnostics.Debug.WriteLine($"注册出错!:{ret1.Message}");
            }
            else
            {
                System.Diagnostics.Debug.WriteLine($"注册成功:{ret1.Message}ID是{ret1.OutputValues["Id"]}");
                ret.Value = (int)ret1.OutputValues["Id"];
            }
        }
        else
        {
            ret.HasError = true;
            ret.Message = "用户名已经存在";
        }
    }
public MFReturnValue<object> Create(SqlTransaction trans, T entity)
{
    SqlParameter[] array = ValueParas(entity);
    array[0].Direction = ParameterDirection.Output;
    array[array.Length - 2].Direction = ParameterDirection.Output;
    array[array.Length - 1].Direction = ParameterDirection.ReturnValue;
    if (trans.IsNullOrEmpty())
    {
        MFSqlHelper.ExecuteNonQuery(ConnectionString, CommandType.StoredProcedure, "{0}_Create".FormatWith(TableName), array);
    }
    else
    {
        MFSqlHelper.ExecuteNonQuery(trans, CommandType.StoredProcedure, "{0}_Create".FormatWith(TableName), array);
    }

    int num = array[array.Length - 1].Value.ToInt();
    MFReturnValue<object> mFReturnValue = new MFReturnValue<object>();
    if (num < 0)
    {
        mFReturnValue.HasError = true;
    }
    else
    {
        mFReturnValue.HasError = false;
        mFReturnValue.OutputValues["Id"] = array[0].Value.ToInt();
    }

    mFReturnValue.Message = array[array.Length - 2].Value.ObjectToString();
    mFReturnValue.ReturnCode = num;
    return mFReturnValue;
}
CREATE PROCEDURE [Account_Create]
(
    @Id int Output,
	@Status tinyint,
	@UserName nvarchar(100),
	@Password varchar(32),
	@Mobile varchar(11),
	@Email varchar(128),
	@Money int,
	@ChannelID smallint,
	@LastServerID int,
	@LastServerName nvarchar(40),
	@LastServerTime datetime,
	@LastRoleID int,
	@LastRoleName nvarchar(40),
	@LastRoleJobID int,
	@CreateTime datetime,
	@UpdateTime datetime,
    @RetMsg nvarchar(255) Output
)
AS
BEGIN
	BEGIN TRY
		SET NOCOUNT ON;
		--自定义逻辑开始
		
		--自定义逻辑结
		
        INSERT INTO Account
			(Status,UserName,Password,Mobile,Email,Money,ChannelID,LastServerID,LastServerName,LastServerTime,LastRoleID,LastRoleName,LastRoleJobID,CreateTime,UpdateTime)
		VALUES
			(@Status,@UserName,@Password,@Mobile,@Email,@Money,@ChannelID,@LastServerID,@LastServerName,@LastServerTime,@LastRoleID,@LastRoleName,@LastRoleJobID,@CreateTime,@UpdateTime)
	
		IF(@@ERROR = 0 AND @@ROWCOUNT > 0)
			BEGIN
	            SET @Id = IDENT_CURRENT('Account')
				SET @RetMsg = '添加成功';
				RETURN 1;
			END
		ELSE
			BEGIN
				SET @RetMsg = '添加失败';
				RETURN -2;
			END
    
		SET NOCOUNT OFF;
	END TRY
	BEGIN CATCH
		SET @RetMsg = ERROR_MESSAGE();
		RETURN -1;
	END CATCH
END


GO

原因:事务没有提交,没有执行transaction.Commit();

Sql指令如何输入日期时间

C# DateTime转字符串需要加单引号

DATE [Account] SET [Token]='e65da5ea-3ef5-4d25-b803-1c749ed145f6',
[ExpireTime]=2026/4/29 20:26:28 WHERE [Id]=1016

连接字符串

是一个ini格式的字符串,也就是用=连接键和值,;隔开字段。一个数据库连接字符串是这样

Data Source=.;
Initial Catalog=UsersDB;
Persist Security Info=True;
User ID=sa;
Password=XXXXXX

Data Source指定服务器名称,Initial Catalog指定数据库名称。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值