Summary of common problems in sql server using stored procedures:

1. The role and detailed explanation of SET ANSI_NULLS ON and SET QUOTED_IDENTIFIER ON in SQL stored procedures

1) SET ANSI_NULLS ON: Indicates that when a null value (null) is equal to (=) or not equal to (<>), it follows the SQL-92 rules. (When the field value after where is empty, the result of select is zero rows/empty.)

2) SET ANSI_NULLS OFF: Indicates that when comparing null values ​​(null) with equal (=) or not equal (<>), the rules of SQL-92 are no longer followed. (When the field value after where is empty, the result of select is the corresponding data row.)

3) SET QUOTED_IDENTIFIER ON: indicates the use of quoted identifiers. Identifiers can be separated by double quotes, but the text must be separated by single quotes.

4) SET QUOTED_IDENTIFIER OFF: It means that the identifier cannot be separated by double quotation marks, otherwise the identifier will be returned as a string value instead of a character. Also, the text part must be separated by single or double quotes.

For details, please move to: https://blog.csdn.net/qq112212qq/article/details/84578263

Two, four kinds of connections about SQL-left outer connection, right outer connection, inner connection, full connection

1. Inner join (typical join operation, using comparison operators like = or <>). Including equal joints and natural joints.
Inner joins use comparison operators to match rows in two tables based on the values ​​of columns common to each table. For example, retrieve all rows with the same student identification number in the students and courses tables.

2. Outer join The outer join can be left outer join, right outer join or complete outer join.
When specifying an outer join in the FROM clause, it can be specified by one of the following groups of keywords:
1) LEFT JOIN or LEFT OUTER JOIN
The result set of the left outer join includes all the left tables specified in the LEFT OUTER clause Rows, not just the rows matched by the joined columns. If a row of the left table does not have a matching row in the right table, all select list columns of the right table in the associated result set row are null values.

2) RIGHT JOIN or RIGHT OUTER JOIN
right outer join is the reverse join of left outer join. All rows of the right table will be returned. If a row of the right table has no matching row in the left table, a null value will be returned for the left table.

3) FULL JOIN or FULL OUTER JOIN
complete outer join returns all rows in the left and right tables. When a row has no matching row in another table, the select list column of the other table contains null values. If there are matching rows between the tables, the entire result set row contains the data values ​​of the base table.

3. Cross join
Cross join returns all rows in the left table, and each row in the left table is combined with all rows in the right table. Cross joins are also called Cartesian products.
The tables or views in the FROM clause can be specified in any order through inner joins or full outer joins; however, when specifying tables or views with left or right outer joins, the order of the tables or views is important. For more information on using left or right outer joins to sort lists, see Using outer joins.

For details, please refer to: https://www.cnblogs.com/yyjie/p/7788413.html

连接查询是SQL查询的核心,连接查询的连接类型选择依据实际需求。
如果选择不当,非但不能提高查询效率,反而会带来一些逻辑错误或者性能低下。
下面总结一下两表连接查询选择方式的依据:

1、 查两表关联列相等的数据用内连接。
2、 Col_L是Col_R的子集时用右外连接。(Col_R是主表,Col_L是关联着的明细表)
3、 Col_R是Col_L的子集时用左外连接。(Col_L是主表,Col_R是关联着的明细表)
4、 Col_R和Col_L彼此有交集但彼此互不为子集时候用全外。
5、 求差操作的时候用联合查询。
多个表查询的时候,这些不同的连接类型可以写到一块。例如:
SELECT T1.C1,T2.CX,T3.CY
FROM TAB1 T1
       INNER JOIN TAB2 T2 ON (T1.C1=T2.C2)
       INNER JOIN TAB3 T3 ON (T1.C1=T2.C3)
       LEFT OUTER JOIN TAB4 ON(T2.C2=T3.C3);
WHERE T1.X >T3.Y;

3. The use of isnull() and sum() in the actual application of stored procedures.

SELECT ISNULL(SUM(ISNULL(ZJGXFKD_JE,0)),0) AS JE 
FROM ZJGXFKD LEFT JOIN ZJGXFKMX ON ZJGXFKMX_NM = ZJGXFKD_NM  
WHERE ZJGXFKD_DJZT <> '1' AND ZJGXFKMX_HTID = @HTBH

In an amount query, due to the incomplete test data, some of the queried order amount was null. When the front-end value was obtained, the result of the calculation was always null. I thought it was a type conversion problem, but it was not resolved. Finally, the isnull() operation is added to the stored procedure.
The sum() function is used when summing the amount, but this function has a feature that when the queried value is null, the summing result will only be null, so isnull() is also needed to assist the summation.

ISNULL():使用指定的替换值替换 NULL。
语法 :  isnull(value1,value2)
        1、value1与value2的数据类型必须一致。
        2、如果value1的值不为null,结果返回value1。
        3、如果value1为null,结果返回vaule2的值。vaule2是你设定的值。
 同时要注意,在sql server中字段为空的写法,
 select je from ZJGXFKMX where je is null\is not null 
 而不是name=null、name=' '       

Four, need to sort the data, the basic usage of row_number() over

用法:
简单的说row_number()从1开始,为每一条分组记录返回一个数字,
例1)ROW_NUMBER() OVER (ORDER BY xlh DESC)  AS 测试
这里是先把xlh列降序,再为降序以后的没条xlh记录返回一个序号。 

例2)ROW_NUMBER() OVER (PARTITION BY COL1 ORDER BY COL2)  AS 测试
表示根据COL1分组,在分组内部根据 COL2排序,
而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)

Five, intercept the specified length of the string: left () function and right () function, corresponding to the substr () function in oracle

语法:LEFT(ARG,LENGTH)、RIGHT(ARG,LENGTH)   
LEFT、RIGHT函数返回ARG最左边、右边的LENGTH个字符串,
ARG可以是CHAR或BINARY STRING。  

例如:RIGHT(HTGY_DDBH,len(HTGY_DDBH)-1) HTGY_DDBH
获取订单编号从右数length-1个长度的编号数据(当时这么写是为了去除订单编号前的字母,
如TK0000123,需要传的数据是K0000123)

There are no left() and right() functions in the Oracle database. If you want to use the corresponding functions in DB2, you can create two functions yourself. The method is as follows

LEFT:
CREATE OR REPLACE FUNCTION "LEFT" (str in varchar2,sublen in integer) return varchar2 is
  strlen integer;
begin

  strlen := length(str);

  if sublen<=0 then
      return '';
  elsif strlen<=sublen then
       return str;
   else
     return SUBSTR(str,0,sublen);
  end if;
 return '';
end LEFT;
RIGHT:
CREATE OR REPLACE FUNCTION "RIGHT" (str in varchar2,sublen in integer) return varchar2 is
  strlen integer;
begin

  strlen := length(str);

  if sublen<=0 then
      return '';
  elsif strlen<=sublen then
       return str;
   else
     return SUBSTR(str,strlen-sublen+1,sublen);
  end if;
 return '';
end RIGHT;

Six, how to create a temporary table

一个简单的例子:关键是在创建前要判断数据库中是否已经有了这个临时表,有的话就删除
if object_id('tempdb..#GT_header') is not null 
	Begin
		   DROP TABLE  #GT_header
	End
	create table #GT_header
	(
	ZHTH nvarchar(35) default '',
	ZHTHXM int default 0,
	KSCHL nvarchar(4) default '',
	ZLSBS nvarchar(1) default '',
	ZHTZT nvarchar(1) default '',
	KTWRTX DECIMAL(15,2) default 0.00,
	KTWRT  DECIMAL(15,2) default 0.00
	)
	insert into #GT_header
	(ZHTH,ZHTHXM,KSCHL,ZLSBS,ZHTZT,KTWRTX,KTWRT)
	select
     RIGHT(HTGY_DWBH,len(HTGY_DWBH)-1) HTGY_DWBH,isnull(HTGY.HTDJ28,'') HTDJ28,
     isnull(HTBD.HTDJ16,0)HTDJ16,	isnull(HTBD.HTDJ17,0.00)HTDJ17, HTGY_C15
	from HTGY left join HTBD on HTGY.HTGY_NM = HTBD.HTBD_HTNM(HTGY为主表,HTBD为子表,所以用左连接)
	where  HTGY.HTGY_NM = @BillNo

注意不要在实际项目中不要轻易用  select * into 新表 from 旧表,
因为有时候旧表(很多时候是产品部已经建好的表,数据格式不能改变)的数据属性
和需要传的数据属性不一致,当出现数据截断时会报数据溢出或者转换异常的错误。
有时候数据字段值产品部也不会添加进去经常出现null的字段值,在运算时很麻烦,还要去排查。
在建表时指定好数据属性,并附上默认值能比较好的避免这种问题,
出现数据转换异常时还要配合cast()和convert()函数,进行强制类型转换。

Type conversion example: https://www.cnblogs.com/davidgu/archive/2011/02/15/1955335.html

Seven, the usage of case when then

--简单case函数
case sex
        when '1' then '男'
        when '2' then '女’
        else '其他' end

--case搜索函数
case when sex = '1' then '男'
     when sex = '2' then '女'
     else '其他' end
     
还有一个需要注重的问题,case函数只返回第一个符合条件的值,
剩下的case部分将会被自动忽略。
--比如说,下面这段sql,你永远无法得到“第二类”这个结果

case when col_1 in ('a','b') then '第一类'
     when col_1 in ('a') then '第二类'
     else '其他' end  

For related questions, please refer to: https://www.cnblogs.com/weihuang6620/p/6904722.html

Eight, the use of views

1. What is a view?
A view is a virtual table, a way of displaying the data in a table after a certain filtering. The view is composed of a predefined query select statement.

2. Features of the view.
The data in the view does not belong to the view itself, but belongs to the basic table. The view can be inserted, updated, and deleted like a table.
The view cannot be modified. After the table is modified or deleted, the view should be deleted and rebuilt.
There is no limit to the number of views, but the naming cannot be repeated with views and tables, and is unique.
Views can be nested, and one view can be nested within another view.
Views cannot be indexed, cannot have associated triggers and default values, and SQL Server cannot use order by sorting behind the view.

3. View function
1. Simplify user operation
2. Can observe the same database from different angles
3. Provides logical independence for reconstructing the database:
use the view to merge or filter the required data, but does not affect the data and structure of the original table

(This is very important, there will be many in actual applications)
4. Provide security protection for confidential data:
different views can be established for different users to achieve security purposes.

建立视图的语法:
Create view 视图名称[(字段1) (字段2) (字段3)…]
AS
Select 查询语句
[with  check  option]
参数:[with check  option]可选项,防止用户对数据插入、删除、更新是操作了视图范围外的基本表的数据。
删除视图的语法:
Drop view 视图名称
说一个实例,有一次在表单开发中,表单上需要展示关联子表的信息,
我用平台自带的load()方法后没办法查出子表的信息,只能查到主表的信息,
尝试调用存储过程又总是失败,最后开发经理提醒我说可以用视图筛选出需要的数据,
然后创建数据模型,在调用load()方法查询。


There is also the need to pay attention to the relationship between the primary key and the unique value. The finally filtered data must have different internal codes. If the internal code of the same data is found, it will be invalid when the getchecked attribute of JS is called. The specific performance is even if the check Multiple data are selected, and only one group of data is selected in the array because their internal codes are the same.

Nine, sql parses the XML format

USE [cwbase0001]
GO
/****** Object:  StoredProcedure [LC00019999].[SP_FSSC_BaseDate_SAPCGHTDDInfor]    Script Date: 2019/6/4 10:09:20 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		Qiang Liu
-- Create date: 2019-5-31
-- Description:	解析XML文件,将字段保存到表中
-- =============================================
ALTER PROCEDURE [lcerp9999].[SP_FSSC_BaseDate_SAPCGHTDDInfor](
	@strXML text, /*<?xml version="1.0" encoding="gb2312"?><'xmldata><item><detailsItem>.</detailsItem>.<detailsItem>.</detailsItem></item>
																	<item><detailsItem>.</detailsItem></item>.</xmldata>*/
	@DataType VARCHAR(20)
)
AS 

BEGIN
DECLARE @hdoc int
----------------------------采购订单合同'EKPO'----------------------------
if @DataType='EKPO'--采购订单合同
begin
if object_id('tempdb..#CGGetSAPDDInfo') is not null 
Begin
       DROP TABLE  #CGGetSAPDDInfo
End
--drop table #CGGetSAPDDInfo
create table #CGGetSAPDDInfo(
--日期类型,数字类型数据用nvarchaer表示
TBID nvarchar(40) not null,--自建数据id列
EBELN nvarchar(10) default '',--采购凭证号
EBELP int default 0,--采购凭证的项目编号
RETPO nvarchar(10) default '',--退货项目
IDNLF nvarchar(35) default '',--供应商使用的物料编号
ZHTHXM int default 0,--合同行项目号
AEDAT nvarchar(20) default '',--采购凭证项目更改日期
ERNAM nvarchar(20) default '',--创建对象的人员名称
MATNR nvarchar(20) default '',--物料号
TXZ01 nvarchar(40) default '',--短文本
MATKL nvarchar(20) default '',--物料组
MENGE decimal(13,3) default 0.000,--采购订单数量   
NETPR nvarchar(20) default '',--采购凭证中的净价(以凭证货币计)
PEINH nvarchar(20) default '',--价格单位
NETWR nvarchar(20) default '',--采购订单货币的订单净值
WAERS nvarchar(10) default '',--货币代码
PSTYP nvarchar(10) default '',--采购凭证中的项目类别
);
--将SAP文件解析,并将数据插入到临时表中

EXEC sp_xml_preparedocument @hdoc OUTPUT, @strXML
print(@hdoc)
INSERT INTO #CGGetSAPDDInfo
SELECT newid(),EBELN ,EBELP ,RETPO ,IDNLF ,
ZHTHXM ,AEDAT ,ERNAM ,MATNR ,TXZ01 ,
MATKL ,MENGE ,NETPR ,PEINH ,NETWR,WAERS,PSTYP 
FROM OPENXML(@hdoc,'xmldata/item/detailsItem',1) --句柄解析的位置
WITH(**

EBELN nvarchar(10)  'EBELN',
EBELP int  'EBELP', 
RETPO nvarchar(10)  'RETPO', 
IDNLF nvarchar(35)  'IDNLF', 
ZHTHXM int  'ZHTHXM', 
AEDAT nvarchar(20)  'AEDAT', 
ERNAM nvarchar(20)  'ERNAM', 
MATNR nvarchar(20)  'MATNR', 
TXZ01 nvarchar(40)  'TXZ01', 
MATKL nvarchar(20)  'MATKL', 
MENGE decimal(13,3)  'MENGE', 
NETPR nvarchar(20)  'NETPR', 
PEINH nvarchar(20)  'PEINH', 
NETWR nvarchar(20)  'NETWR', 
WAERS nvarchar(10)  'WAERS', 
PSTYP nvarchar(10)  'PSTYP' 
);

--将临时表数据插入到正式存储表
--1、更新编号重复的订单
update CGGetSAPDDInfo  set 
CGGetSAPDDInfo.EBELN=#CGGetSAPDDInfo.EBELN ,
EBELP=#CGGetSAPDDInfo.EBELP ,
RETPO=#CGGetSAPDDInfo.RETPO ,
IDNLF=#CGGetSAPDDInfo.IDNLF ,
ZHTHXM=#CGGetSAPDDInfo.ZHTHXM ,
AEDAT=#CGGetSAPDDInfo.AEDAT,
ERNAM=#CGGetSAPDDInfo.ERNAM ,
MATNR=#CGGetSAPDDInfo.MATNR ,
TXZ01=#CGGetSAPDDInfo.TXZ01 ,
MATKL=#CGGetSAPDDInfo.MATKL ,
MENGE=#CGGetSAPDDInfo.MENGE ,
NETPR=#CGGetSAPDDInfo.NETPR ,
PEINH=#CGGetSAPDDInfo.PEINH ,
NETWR=#CGGetSAPDDInfo.NETWR, 
WAERS=#CGGetSAPDDInfo.WAERS, 
PSTYP=#CGGetSAPDDInfo.PSTYP

from #CGGetSAPDDInfo 
WHERE CGGetSAPDDInfo.EBELN=#CGGetSAPDDInfo.EBELN


--2、插入不存在编号的订单
insert into CGGetSAPDDInfo 
(TBID ,EBELN ,EBELP ,RETPO ,IDNLF ,
ZHTHXM ,AEDAT ,ERNAM ,MATNR ,TXZ01 ,
MATKL ,MENGE ,NETPR ,PEINH ,NETWR,WAERS,PSTYP)

select 
newid(),EBELN ,EBELP ,RETPO ,IDNLF ,
ZHTHXM ,AEDAT ,ERNAM ,MATNR ,TXZ01 ,
MATKL ,MENGE ,NETPR ,PEINH ,NETWR,WAERS,PSTYP 
from #CGGetSAPDDInfo
where not exists (select 1 from CGGetSAPDDInfo where CGGetSAPDDInfo.EBELN = #CGGetSAPDDInfo.EBELN) 
end 

Guess you like

Origin blog.csdn.net/zhuyin6553/article/details/96833720