无需言 做自己 业 ,精于勤 荒于嬉.

SQLServer Link DB Server

发表日期:2022-08-20 09:56:53 | 来源: | 分类:SQLServer

      示例1
--查看当前链接情况:
select * from sys.servers;

--使用 sp_helpserver 来显示可用的服务器
Exec sp_helpserver

--显示使用sp_addlinkedserver来增加服务器链接
EXEC sp_addlinkedserver
    @server='LINKABC',--被访问的服务器别名
    @srvproduct='',
    @provider='SQLOLEDB',
    @datasrc='192.168.0.10\sql2008' --要访问的服务器IP[\实例名有就写没有]

--然后使用sp_addlinkedsrvlogin 来增加用户登录链接
EXEC sp_addlinkedsrvlogin
    'LINKABC', --被访问的服务器别名
    'false',
    NULL,
    'root', --帐号
    '123456' --密码

访问:
select * from [LINKABC].[abcDB].dbo.Users where uid = 1;
也支持IP形式:
select * from [192.168.0.10].[abcDB].dbo.Users where uid = 1;

-- 删除数据库链接
--与创建相反,要先删除登录账户
exec sp_droplinkedsrvlogin 'LINKABC',null

--然后再删除数据库链接
exec sp_dropserver 'LINKABC'

阅读全文 »

SQLServer 存储过程详解

发表日期:2022-08-19 15:57:32 | 来源: | 分类:SQLServer

      示例1
-- 如果没有参数 可以不写参数
CREATE PROCEDURE [存储名] @参数1 int, @参数2 varchar(50), @参数3 varchar(2000),@参数4 varchar(100)
as

-- 存储的主体

go
      示例2
exec [存储过程名字] @参数1=1,@参数2='aaa', @参数3sql='bbbb',@参数4where ='ccccc';
或者简写,即按字段顺序
exec [存储过程名字] 1,'aaa', 'bbbb','ccccc';

exec 也可以写成全称 execute
      示例3
-- 参数可以传入SQL语句直接在存储过程里执行,通常不建议这样干!
exec (@参数);

-- 传入的参数也可以是半截sql,然后再拼起来执行,通常不建议这样干!
-- 而且通常这么干都是在代码里把接收到的参数拼起来传,十有八九有SQL注入漏洞
exec ('delete from TestTab2 where a=b and d=c and '+@参数4where);
      示例4
-- 定义临时表
DECLARE @table_tmp table
(
   a int,
   b VARCHAR(50),
   c int,
   d int,
   e VARCHAR(50),
   f VARCHAR(50),
   g DECIMAL DEFAULT 0
);

-- 写法用法和普通表没什么区别,考验你的SQL基础能力罢了
insert into @table_tmp (a, b, c, d) select uid,username,age,10 from Users where type=3;

update @table_tmp set e=(select role_name from user_profile where uid = a)  where age > 18;

UPDATE t set t.f = r.role_name FROM @table_resoult as t, user_role as r where r.uid = t.a;

update @table_tmp set g=(select sum(money) from user_account where uid = a) where g = 0;

update c set c.d=b.score from @table_tmp c join ( select * from xxxxx ) b on c.a = b.uid and c.e = b.role;

--最后达到你想要的结果集了,你可以把虚拟表的数据插入到目标真实表
insert into targetTab(a1,b1,c1,d1,e1,f1,g1) select a,b,c,d,e,f,g from @table_tmp;
-- 或者存储过程直接返回临时表的结果
select *  from @table_tmp;
      示例5
--可以定义变量
declare @var1 varchar(50)

--给定义的变量赋值
select @username = username from users where UID = 1;

--使用变量
update user_house set update_time=getdate(), username=@username where uid = 1;
      示例6
--开启事务
begin tran

-- 这里进行业务操作
-- ……

--如果有错
if (0 <> @@ERROR)
    begin 
    
        --事务回滚
        rollback tran;
        
        
        -- 返回错误码
        select -1;
    end
else
    begin 
    
        --提交事务
        commit tran;
        
        -- 可以返回修改行数或 其它内容
        select @@ROWCOUNT;
    end
      示例7
--定义变量
declare @uid int,@username varchar(50);

-- 定义游标 填充数据
declare c1 cursor for select UID,UName  from Users where uuid <> 0;

--开启游标
open c1 aa:fetch next from c1 into @uid,@username

-- 循环
while @@fetch_Status = 0
    begin
        -- 业务逻辑
    end
    
    
-- 关闭游标
close c1

-- 销毁游标
deallocate c1

阅读全文 »

SQLServer 大坑之事务回滚占自增ID

发表日期:2022-08-18 11:33:59 | 来源: | 分类:SQLServer

主键如果是自增的,当你使用事务时,即便是事务回滚了,你的下一个ID会被占用,再次插入会跳一个数。

这个大坑在一些业务场景下极其讨厌,比如这张表的ID是某编号你希望是连续的那就很膈应了。

image.png

你可以看到上面的例子,执行多次后ID全是间隔的,就是因为回滚事务的那条也占用了ID自增。

注意:mysql也是如此

阅读全文 »

SQLServer 存储报错:SQLSTATE[IMSSP]: The active result for the query contains no fields.

发表日期:2022-08-16 17:00:00 | 来源: | 分类:SQLServer

存储报错:SQLSTATE[IMSSP]: The active result for the query contains no fields.

原因:

一般执行execute语句,也就是增删改语句会返回修改记录数的行数。执行select 是返回记录。

存储里可能是先执行了增删改,最后是select 返回结果,就会报这个错。

在存储里增加这句话,让存储不返回影响的记录数就可以了。

SET NOCOUNT ON

阅读全文 »

SQLServer 大坑之导入数据

发表日期:2022-08-16 16:49:34 | 来源: | 分类:SQLServer

Cannot insert explicit value for identity column in table 'test' when IDENTITY_INSERT is set to OFF

这句报错的大致意思就是这张表有自增列,不能直接导入。

SQLServer 导入表,如果这张表的ID是自增那就非常烦,导入会报错。提示你必须先允许插入自增,插入完成再关闭。

set IDENTITY_INSERT 表名 on

insert into ……

insert into ……

set IDENTITY_INSERT 表名 off

当然要是一张表还好办,我要导入N张表,可是把我烦死了,而且单表SQL文件特别大,打开都费劲。

阅读全文 »

SQLServer 大坑之浮点数显示问题

发表日期:2022-08-15 16:47:01 | 来源: | 分类:SQLServer

以下情况在php+SQLserver下经过验证是存在问题的,其它语言请自酌。

一、字段类型是float类型时

image.png

image.png  

输出

image.png 

 显示正常,十分具有迷惑性,开发的时候你以为是没问题的,

但是

image.png

输出

image.png 

150.12 显示为 15.119999999999999

这是太坑了,我们的项目是重构一个用了15年+的项目,库不变只做程序,项目里见到最多的字段就是金额小数点,做到后面发现这个问题,所有输出的位置到处都得格式化去改!

还有一个问题是,如果你希望的是x.xx这种保留两位的格式,不好意思,不建议用float类型!因为12.00 进库即存为12,出库也12,不格式化没法是12.00!

对比之下mysql是没有问题的,因为是是这样定义的float(9,2)保留两位!


二、字段类型是 decimal(18, 2) 类型时

0.00 显示为 .00

image.png

输出:

image.png

导致于 所有显示地方都得把 .00 换成 0.00。

(后发现可能是php-SQLserver驱动的兼容问题一个项目用的pdo_dblib显示是好的,一个用的pdo_sqlsrv显示不正常,可能跟驱动版本有关系,反正用php+SQLserver的小伙伴格外注意一下),

阅读全文 »

SQLServer 大坑之数字乘除计算

发表日期:2022-08-15 12:16:52 | 来源: | 分类:SQLServer

10 / 4 * 4 = ?  , 小学毕业都知道应该还是10,

我们用mysql试一下:

image.png

依然是10,其实当计算出小数,mysql会自动转型为float,但是注意,SQLserver不会!

image.png

得出的结果是8! 为什么是8呢,有点离谱。

因为SQLserver是强类型的,10/4 = 2 ,2*4=8,因此如果你的字段是int类型的你想在SQL里做乘除那你可得想好了,记得先把计算的字段转型为float

image.png

阅读全文 »

SQLServer 大坑之null 判断

发表日期:2022-08-15 12:00:34 | 来源: | 分类:SQLServer

例如

image.png

三条数据,我们找出 misMoney是null的

image.png

然而一条也没出来!

mysql 的null 你写 where a = null / where a <> null 都没毛病,当然我一直也认为其实能这样判断是最好最方便,但是SQLserver不支持!

尤其现在绝大多数程序员及项目都用的是mysql,所以很多程序员没用过甚至不了解SQLserver。我面试过很多程序员,答对的很少,全然不知SQL语句 null 的正确判断写法。

正确写法

 image.png

一定要有 is null  或 is not null !

参考另一篇文章:

SQLServer大坑之<>判断

阅读全文 »

SQLServer 大坑之不等于判断

发表日期:2022-08-15 11:50:20 | 来源: | 分类:SQLServer

例如有三条数据:

image.png

我们想找出 posMoney和misMoney不一致的数据,逻辑很简单 我们通常想到且写的是:

where posMoney <> misMoney ,理论上出的结果是王五和李四。

然后我们看结果

image.png

只有一条王五!!  20000和null 的竟然出不来!

这就是SQLserver的大坑,一定要注意,mysql是没有问题的,但是SQLserver是不能和可能存在null列进行对比,

当然我事先是知道这个的,但是!!有时候我们认为的数据实际不应该有null,但现实是前几天发现业务系统里这列数据居然因为某些异常情况存在很多null值,以至于我这样写成为了被错误。这是最坑的,这才是更是应该注意的,所以代码最好把所有可能性想到,避免让别人的错误成为自己的错。

所以,在SQLserver里如果是金额等严谨性判断<> 最好这样写:

image.png

不管你认为可不可能有null 总之先把null替换为数字0或空字符串'',然后再对比 <>,多么痛的领悟……

阅读全文 »

MYSQL 创建用户及数据库,并赋予权限

发表日期:2022-08-12 17:01:56 | 来源: | 分类:MYSQL

      示例1
#创建一个名为 testUser 的用户,%指任意主机可以连接 或 127.0.0.1 指定ip连接
#需要特别注意的是:'testUser'@'%'与'testUser'@'localhost' 看起来像是一个用户,事实上要注意 这是两个用户!可以有不同的权限
CREATE USER 'testUser'@'%' IDENTIFIED WITH mysql_native_password;

#给这个用户赋予一些查询mysql环境的权限
GRANT USAGE ON *.* TO 'testUser'@'%' REQUIRE NONE WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0;

#给这个用户设置密码
SET PASSWORD FOR 'testUser'@'%' = '123456';

#创建数据库 testDB
CREATE DATABASE IF NOT EXISTS `testDB`;

#把 testDB库的所有权限 赋予 'testUser'@'%'的登录用户
GRANT ALL PRIVILEGES ON `testDB`.* TO 'testUser'@'%';


# `testDB\_%`.* TO 'testDB'@'%'; 这里可以使用通配符% 代表 把testDB_开头的数据库都给这个用户

阅读全文 »

PHP杂项 ip白黑名单验证

发表日期:2022-08-06 16:12:05 | 来源: | 分类:PHP杂项

      示例1
function validate_ip($ip, $allow_ip_map)
{
    if (in_array($ip, $allow_ip_map)) {
        return true;
    } else {
        $flag = false;
        $ip_pos = explode('.', $ip);
        foreach ($allow_ip_map as $val) {
            if (strpos($val, '-') !== false) {//范围
                $ip_range = explode('-', $val);
                if (ip2long($ip_range[0]) * -1 >= ip2long($ip) * -1 && ip2long($ip_range[1]) * -1 <= ip2long($ip) * -1) {
                    $flag = true;
                    break;
                }
            } else {//单个
                if (strpos($val, '*') !== false) {//发现有*号替代符
                    $arr = explode('.', $val);
                    $flag = true;//用于记录循环检测中是否有匹配成功的
                    for ($i = 0; $i < 4; $i++) {
                        if ($arr[$i] != '*') {//不等于* 就要进来检测,如果为*符号替代符就不检查
                            if ($arr[$i] != $ip_pos[$i]) {
                                $flag = false;
                                break;//终止检查本个ip 继续检查下一个ip
                            }
                        }
                    }
                    if ($flag) {//如果是true则终止匹配
                        break;
                    }
                }
            }
        }
        return $flag;
    }
}

阅读全文 »

PHP杂项 自实现getallheaders函数 获取header信息

发表日期:2022-08-06 16:10:41 | 来源: | 分类:PHP杂项

      示例1
if (!function_exists('getallheaders')) {
    /**
     * @return mixed
     * @deprecated 推荐使用request()->header()
     */
    function getallheaders()
    {
        foreach ($_SERVER as $name => $value) {
            if (substr($name, 0, 5) == 'HTTP_') {
                $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
            }
        }
        return $headers;
    }
}

阅读全文 »

PHP杂项 随机颜色

发表日期:2022-08-06 16:09:53 | 来源: | 分类:PHP杂项

      示例1
function random_color()
{
    $rand = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
    $color = '#' . $rand[rand(0, 15)] . $rand[rand(0, 15)] . $rand[rand(0, 15)] . $rand[rand(0, 15)] . $rand[rand(0, 15)] . $rand[rand(0, 15)];
    return $color;
}

阅读全文 »

PHP杂项 中文全角半角互转

发表日期:2022-08-06 16:06:03 | 来源: | 分类:PHP杂项

      示例1
/**
 * 半角全角互转
 * @param string $str
 * @param string $args2 0半角到全角 1全角到半角
 * @return string
 **/
function SBC_DBC($str, $args2=0)
{
    $DBC = array(
        '0', '1', '2', '3', '4',
        '5', '6', '7', '8', '9',
        'A', 'B', 'C', 'D', 'E',
        'F', 'G', 'H', 'I', 'J',
        'K', 'L', 'M', 'N', 'O',
        'P', 'Q', 'R', 'S', 'T',
        'U', 'V', 'W', 'X', 'Y',
        'Z', 'a', 'b', 'c', 'd',
        'e', 'f', 'g', 'h', 'i',
        'j', 'k', 'l', 'm', 'n',
        'o', 'p', 'q', 'r', 's',
        't', 'u', 'v', 'w', 'x',
        'y', 'z', '-', ' ', ':',
        '.', ',', '/', '%', '#',
        '!', '@', '&', '(', ')',
        '<', '>', '"', ''', '?',
        '[', ']', '{', '}', '\',
        '|', '+', '=', '_', '^',
        '¥', ' ̄', '`'
    );
    $SBC = array( //半角
        '0', '1', '2', '3', '4',
        '5', '6', '7', '8', '9',
        'A', 'B', 'C', 'D', 'E',
        'F', 'G', 'H', 'I', 'J',
        'K', 'L', 'M', 'N', 'O',
        'P', 'Q', 'R', 'S', 'T',
        'U', 'V', 'W', 'X', 'Y',
        'Z', 'a', 'b', 'c', 'd',
        'e', 'f', 'g', 'h', 'i',
        'j', 'k', 'l', 'm', 'n',
        'o', 'p', 'q', 'r', 's',
        't', 'u', 'v', 'w', 'x',
        'y', 'z', '-', ' ', ':',
        '.', ',', '/', '%', '#',
        '!', '@', '&', '(', ')',
        '<', '>', '"', '\'', '?',
        '[', ']', '{', '}', '\\',
        '|', '+', '=', '_', '^',
        '$', '~', '`'
    );
    if ($args2 == 0)
        return str_replace($SBC, $DBC, $str);  //半角到全角
    if ($args2 == 1)
        return str_replace($DBC, $SBC, $str);  //全角到半角
    else
        return false;
}

阅读全文 »

PHP杂项 字符和unicode互转

发表日期:2022-08-06 16:03:20 | 来源: | 分类:PHP杂项

      示例1
/**
 * 将unicode转换成字符
 * @param int $unicode
 * @return string UTF-8字符
 **/
function unicode2Char($unicode)
{
    if ($unicode < 128) return chr($unicode);
    if ($unicode < 2048) return chr(($unicode >> 6) + 192) .
        chr(($unicode & 63) + 128);
    if ($unicode < 65536) return chr(($unicode >> 12) + 224) .
        chr((($unicode >> 6) & 63) + 128) .
        chr(($unicode & 63) + 128);
    if ($unicode < 2097152) return chr(($unicode >> 18) + 240) .
        chr((($unicode >> 12) & 63) + 128) .
        chr((($unicode >> 6) & 63) + 128) .
        chr(($unicode & 63) + 128);
    return false;
}

/**
 * 将字符转换成unicode
 * @param string $char 必须是UTF-8字符
 * @return int
 **/
function char2Unicode($char)
{
    switch (strlen($char)) {
        case 1 :
            return ord($char);
        case 2 :
            return (ord($char{1}) & 63) |
                ((ord($char{0}) & 31) << 6);
        case 3 :
            return (ord($char{2}) & 63) |
                ((ord($char{1}) & 63) << 6) |
                ((ord($char{0}) & 15) << 12);
        case 4 :
            return (ord($char{3}) & 63) |
                ((ord($char{2}) & 63) << 6) |
                ((ord($char{1}) & 63) << 12) |
                ((ord($char{0}) & 7) << 18);
        default :
            trigger_error('Character is not UTF-8!', E_USER_WARNING);
            return false;
    }
}

阅读全文 »

PHP杂项 日期时间友好展示为今天/昨天/前天/分钟/小时/天前

发表日期:2022-08-06 16:00:35 | 来源: | 分类:PHP杂项

      示例1
function datetime_friendly($datetime)
{
    $time = strtotime($datetime);

    $second = time() - $time;
    if ($second < 60) {
        $str = '刚刚';
    } elseif ($second < 60 * 60) {
        $min = floor($second / 60);
        $str = $min . ' 分钟前';
    } elseif ($second < 60 * 60 * 24) {
        $h = floor($second / (60 * 60));
        $str = $h . ' 小时前';
    } elseif ($second < 60 * 60 * 24 * 3) {
        $d = floor($second / (60 * 60 * 24));

        $rtime = date("H:i", $time);

        if ($d == 1)
            $str = '昨天 ' . $rtime;
        else
            $str = '前天 ' . $rtime;
    } elseif ($time > mktime(0, 0, 0, 1, 1, date('Y'))) {
        $str = date("m月d日", $time);
    } else {
        $str = date("Y年m月d日", $time);
    }

    return $str;
}

阅读全文 »

PHP杂项 递归创建多级目录

发表日期:2022-08-06 15:58:05 | 来源: | 分类:PHP杂项

      示例1
/**
 * 检测目录是否存在/创建多级目录
 * @param String $path 目录路径[D:/a/b] or [a/b/c] or [./a/b] or [/a/b/c] or [../../a/b]
 * @return boolean 目录是否存在/多级目录是否创建成功
 */
function quick_make_dirs($path)
{
    if (is_dir($path)) return true;

    $path = str_replace(ROOT_PATH, '', preg_replace('/[\\\|\/]+/', DS, $path));

    $dirs = explode(DS, $path);

    $dir = ROOT_PATH;

    for ($i = 0; $i < count($dirs); $i++) {

        if ($dirs [$i] == '') continue;

        $dir .= $dirs [$i] . DS;

        if (!is_dir($dir)) {
            //mkdir($dir, 0777) or TRIGGER_ERROR("!-目录[$dir]不可写,请手动设置目录权限!");
            if (!mkdir($dir, 0777)) {
                break;
            }

        }
    }

    return is_dir($dir) ? true : false;
}

阅读全文 »

PHP杂项 字符串截取追加...

发表日期:2022-08-06 15:51:11 | 来源: | 分类:PHP杂项

      示例1
/**
 * 字符串截取
 * @param String $str 要截取的字符串
 * @param int $start 开始位置
 * @param int $length 截取长度
 * @param String $ellipsis 省略符
 * @return String 截取后的字符串
 */
function quick_mb_substr($str, $start, $length, $ellipsis = '...')
{
    $str_length = mb_strlen($str, 'utf8');

    if ($str_length <= $start + $length) {
        return mb_substr($str, $start, $str_length - $start, 'utf8');
    }

    return mb_substr($str, $start, $length, 'utf8') . $ellipsis;
}

阅读全文 »

PHP杂项 批量反/转义特殊字符,数据库安全过滤写入,支持字符串、多维数组、对象集合

发表日期:2022-08-06 15:46:30 | 来源: | 分类:PHP杂项

      示例1
/**
 * 批量转义特殊字符
 * '&' (ampersand) becomes '&amp;'
 * '"' (double quote) becomes '&quot;' when ENT_NOQUOTES is not set.
 * "'" (single quote) becomes '&#039;' (or &apos;) only when ENT_QUOTES is set.
 * '<' (less than) becomes '&lt;'
 * '>' (greater than) becomes '&gt;'
 *
 * @param array|object|string $data
 * @return array|object|string
 * @example
 * $new = htmlspecialchars("<a href='test'>Test</a>", ENT_QUOTES);
 * echo $new; // &lt;a href=&#039;test&#039;&gt;Test&lt;/a&gt;
 *
 */
function encode_special_symbol($data)
{
    if (is_array($data)) {
        foreach ($data as $key => $value) $data [$key] = encode_special_symbol($value);
    } elseif (is_object($data)) {
        foreach ($data as $key => $value) $data->$key = encode_special_symbol($value);
    } else {
        $data = htmlspecialchars(trim($data));
    }
    return $data;
}

/**
 * 批量反转义特殊字符
 * @param $data
 * @return array|string
 */
function decode_special_symbol($data)
{
    if (is_array($data)) {
        foreach ($data as $key => $value) $data [$key] = decode_special_symbol($value);
    } elseif (is_object($data)) {
        foreach ($data as $key => $value) $data->$key = decode_special_symbol($value);
    } else {
        $data = htmlspecialchars_decode($data);
    }
    return $data;
}

阅读全文 »

PHP杂项 压缩HTML,去换行空格,注释

发表日期:2022-08-06 15:43:48 | 来源: | 分类:PHP杂项

      示例1
function quick_compress_html($html)
{
    $html = str_replace(["\r\n", "\n", "\t"], ['', '', ''], $html);
    $_pattern = array("/> *([^ ]*) *</", "/[\s]+/", "/<!--[^!]*-->/", "/\" /", "/ \"/", "'/\*[^*]*\*/'", "/ \/\*[^.]*\*\//");
    $_replace = array(">\\1<", " ", "", "\"", "\"", " ", " ");
    return preg_replace($_pattern, $_replace, $html);
}

阅读全文 »

全部博文(1589)
集速网 copyRight © 2015-2025 宁ICP备15000399号-1 宁公网安备 64010402001209号
与其临渊羡鱼,不如退而结网
欢迎转载、分享、引用、推荐、收藏。