分类 数据库 下的文章

php读取ms sql server数据的方法和注意事项

在windows平台,php5.3+读取sql server里面的数据,其实用php_pdo_odbc.dll扩展是最好的选择,SQL语句的兼容性很高,比ms自家出品的sqlsrv(Microsoft Drivers for PHP for SQL Server)扩展强太多了。

一、下面先吐槽一下sqlsrv一些不爽的地方:

1、获取的数据编码默认是UTF-8的,想改为其它编码的数据有点麻烦,虽说它可以设为用系统的编码,但是这里有个很大的问题, 假如你的系统是gbk的,但是获取到的数据有些还是会变为UTF-8的。尽管可以用iconv转换编码,但这个iconv本来就不能转换全部的中文,说不定某些中文就被忽略掉了,不敢用iconv转换成GBK的。

2、某些字段的类型不能自动映射,会出现映射错误,提示数据类型不正确。

3、一些复杂点的SQL语句居然查询不到结果,这个相当无语了,我的SQL语句中出现了中文,居然都返回不了查询结果,不知道是不是编码问题,我也不想测试了。还有个非常奇怪的地方,SQL语句里面用到了ISNULL这个函数,它居然也不执行,取不到任何结果。

总的来说这个东西只能用来处理下英文类的数据,简单点的SQL语句。复杂点的它根本就不行,兼容性太差。

二、用php_pdo_odbc.dll可以很轻松的处理复杂SQL语句及编码问题。当然用pdo_odbc也出现了一点应该注意的问题,不然我也不会在这里吐槽了。读取nvarchar或者nchar字段的数据时,可能会把该字段后面部分的中文给弄成乱码。因为nvarchar字段是按字符存储的,而odbc是按字节读取的,它好像不能处理多字节字符。当它读取到字段长度那么多个字节的时候,后面的字节就被它搞成乱码了,一开始这个问题百思不得其解。有什么办法可以让它不乱码呢,其实你只需要用convert转换一下数据类型为varchar就行了。如:select convert(varchar(两倍的nvarchar字段的长度), nvarchar字段名) from table1。varchar一定要带长度,最好是这个nvarchar字段长度的两倍,这样转换一下后,你获取的数据就不会出现乱码了。

[转]详解SQL Server的两个存储过程:sp_MSforeachtable/sp_MSforeachdb

1.简介:
作为DBA会经常需要检查所有的数据库或用户表,比如:检查所有数据库的容量;看看指定数据库所有用户表的容量,所有表的记录数...,我们一般处理这样的问题都是用游标分别处理处理,比如:在数据库检索效率非常慢时,我们想检查数据库所有的用户表,我们就必须通过写游标来达到要求;如果我们用sp_MSforeachtable就可以非常方便的达到相同的目的:EXEC sp_MSforeachtable @command1="print '?' DBCC CHECKTABLE ('?')"
系统存储过程sp_MSforeachtable和sp_MSforeachdb,是微软提供的两个不公开的存储过程,从mssql6.5开始。存放在SQL Server的MASTER数据库中。可以用来对某个数据库的所有表或某个SQL服务器上的所有数据库进行管理,后面将对此进行详细介绍。

- 阅读剩余部分 -

[转]SQL Server 跨库复制表数据的解决办法

跨库复制表数据,有很多种方法,最常见的是写程序来批量导入数据了,但是这种方法并不是最优方法,今天就用到了一个很犀利的方法,可以完美在 Sql Server 2005 和 Sql Server 2008 中执行!
格式如下:

insert into tableA
SELECT * FROM
OPENDATASOURCE('SQLOLEDB', 'Data Source=127.0.0.1;User ID=sa;Password=sasasa').databaseName.dbo.tableB

- 阅读剩余部分 -

转:MS SQL自定义函数查找相似记录并计算相似度

问题描述:

表结构如下

ShopID    Tag                    TagType
--------------------------------------
1      手抓肉 烤肉 抓饭 拉条子      2
2      烤肉 抓饭 拉条子             2
3      手抓肉 抓饭 拉条子           2
4      手抓肉 烤肉 抓饭             2
5      囊坑肉 大盘鸡 抓饭 拉条子    2
6      拌面 烤肉 抓饭 拉条子        2
7      手抓肉 大盘鸡 抓饭 拉条子    2

需要搜索与提供的Tag内容(如手抓肉 烤肉 抓饭)相似的记录,并按照相似度从高到低排列,其中Tag是以空格分割的,如上的内容就是说Tag包含手抓肉,烤肉,抓饭,而其他数据只要包含其中一条就表示他们相似,包含的越多就表示越相似。

用自定义函数查找记录和计算相似度,查询时按相似度排序,相似度的定义是,与提供的Tag中的一项相符的就加1,以最后的和来表示相似度。

- 阅读剩余部分 -

Mysql日期和时间函数详解

对于每个类型拥有的值范围以及并且指定日期何时间值的有效格式的描述见7.3.6 日期和时间类型。

这里是一个使用日期函数的例子。下面的查询选择了所有记录,其date_col的值是在最后30天以内:

mysql> SELECT something FROM table
WHERE TO_DAYS(NOW()) - TO_DAYS(date_col) <= 30;

DAYOFWEEK(date)
返回日期date的星期索引(1=星期天,2=星期一, ……7=星期六)。这些索引值对应于ODBC标准。
mysql> select DAYOFWEEK('1998-02-03');
-> 3

WEEKDAY(date)
返回date的星期索引(0=星期一,1=星期二, ……6= 星期天)。
mysql> select WEEKDAY('1997-10-04 22:23:00');
-> 5
mysql> select WEEKDAY('1997-11-05');
-> 2

- 阅读剩余部分 -

SQLServer 解决“错误15023:当前数据库中已存在用户或角色”

在使用SQL Server 2000时,我们经常会遇到一个情况:需要把一台服务器上的数据库转移到另外一台服务器上。而转移完成后,需要给一个”登录”关联一个"用户"时,往往会发生错误:

错误15023:当前数据库中已存在用户或角色

这个问题非常棘手,几经排常找到了原因与解决方法,因为这个问题与解决方法均比较复杂,所以把这个过程中的一些经验纪录下来与大家分享,希望能对大家以后的类似操作有所帮助。

原因及解决办法如下:

首先介绍一下sql server中“登录”与“用户”的区别,“登录”用于用户身份验证,而数据库“用户”帐户用于数据库访问和权限验证。登录通过安全识别符 (SID) 与用户关联。将数据库恢复到其他服务器时,数据库中包含一组用户和权限,但可能没有相应的登录或者登录所关联的用户可能不是相同的用户。这种情况被称为存在“孤立用户”。此时是不能通过新建登录或者是对同名登录授予对应数据库的“用户”权限来解决登录问题,因为SQL Server会报出“错误15023:当前数据库中已存在用户或角色”。为了解决这个问题,需要调用系统存储过程sp_change_users_login,具体用法如下:

Use netzs

go
sp_change_users_login 'update_one', 'yjsy232', 'yjsy232'

其中netzs为存在孤立用户的数据库,update_one是存储过程的参数,表示只处理一个用户,前一个yjsy232是“用户”,后一个yjsy232是“登录”,以上这个SQL表示将服务器登录“yjsy232”与 netzs 数据库用户“yjsy232”重新连接起来。这样就可以正常使用数据库了。

清空MSSQL数据库日志与set recovery simple

1.打开查询分析器,输入命令 DUMP TRANSACTION 数据库名称 WITH NO_LOG

2.再打开企业管理器--右键你要压缩的数据库--所有任务--收缩数据库--收缩文件--选择日志文件--在收缩方式里选择收缩至XXM,这里会给出一个允许收缩到的最小M数,直接输入这个数,确定就可以了。

如果以后不想要它变大 SQL2000下使用: 在数据库上点右键->属性->选项->故障恢复-模型-选择-简单模型。 或用SQL语句: alter database 数据库名 set recovery simple

SQL Server2008:解决“阻止保存要求重新创建表的更改”

在SQL Server 2008企业管理器中更改表结构时(特别是修改了某个字段的类型时),总是会弹出:必须要先删除原来的表,然后重新创建新表,才能完成表的更改,如果强行更改会出现以下提示:不允许保存更改。您所做的 更改要求删除并重新创建以下表。您对无法重新创建的标进行了更改或者启用了“阻止保存要求重新创建表的更改”选项。如何避免此提示,可从“工具”菜单中 选择“选项”,在“选项”对话框中,选择Designers,选择“表设计器和数据库设计器”,清除“ 阻止保存要求重新创建表的更改”复选框。

SQLServer添加用户:错误15023:当前数据库中已存在用户或角色

在使用SQL Server 2000时,我们经常会遇到一个情况:需要把一台服务器上的数据库转移到另外一台服务器上。而转移完成后,需要给一个"登录"关联一个"用户"时,往往会 发生错误:

错误15023:当前数据库中已存在用户或角色

这个问题非常让人头疼,几经排常找到了原因与解决方法,因为这个问题与解决方法均比较复杂,所以把这个过程中的一些经验纪录下来与大家分享,希望能对大家以后的类似操作有所帮助,原因及解决办法如下:

首先介绍一下sql server中“登录”与“用户”的区别,“登录”用于用户身份验证,而数据库“用户”帐户用于数据库访问和权限验证。登录通过安全识别符 (SID) 与用户关联。将数据库恢复到其他服务器时,数据库中包含一组用户和权限,但可能没有相应的登录或者登录所关联的用户可能不是相同的用户。这种情况被称为存 在“孤立用户”。此时是不能通过新建登录或者是对同名登录授予对应数据库的“用户”权限来解决登录问题,因为SQL Server会报出“错误15023:当前数据库中已存在用户或角色”,为了解决这个问题,需要调用系统存储过程 sp_change_users_login,具体用法如下:

[code language="sql"]Use tablename

go

sp_change_users_login 'update_one', 'junstyle', 'junstyle'
[/code]

其中tablename为存在孤立用户的数据库,update_one是存储过程的参数,表示只处理一个用户,前一个 junstyle是“用户”,后一个junstyle是“登录”,以上这个SQL表示将服务器登录“junstyle”与 tablename数据库用户“junstyle”重新连接起来。这样就可以正常使用数据库了。

在SQL SERVER数据库中获取自增长ID的三种方法的比较

SCOPE_IDENTITY

返回插入到同一作用域中的 IDENTITY 列内的最后一个 IDENTITY 值。一个作用域就是一个模块——存储过程、触发器、函数或批处理。因此,如果两个语句处于同一个存储过程、函数或批处理中,则它们位于相同的作用域中。

IDENT_CURRENT

返回为任何会话和任何作用域中的指定表最后生成的标识值。这个函数需要一个以表名为值的变量,也就是说虽然不受会话和作用域的限制,却会受到表的限制。

@@IDENTITY

返回最后插入的标识值。

体会:加上事务处理,两个函数一个变量没有本质区别。不加事务处理两个函数一个变量受到其他会话、作用域的影响不一样。

一直以来都是使用@@identity来获得最后一个插入到表的记录的identity值,最近发现这种方法在某种情况是不可靠的,先来看看两个概念
作用域:在SQL SERVER作用域就是一个模块-存储过程,触发器,函数或批处理
会话: 一个用户连接产生的所有上下文信息

相同点:都是返回最后插入的标识值
不同点
@@identity:返回当前会话最后一个标识值,不限于特定的作用域;
ident_current('tablename'):返回任何会话,任何作用域中的指定表中生成的最后一个标识值;
scope_identity:返回当前会话当前作用域任何表生成的最后一个标识值 。

例如,有两个表 T1 和 T2,在 T1 上定义了一个 INSERT 触发器。当将某行插入 T1 时,触发器被激发,并在 T2 中插入一行。此例说明了两个作用域:一个是在 T1 上的插入,另一个是作为触发器的结果在 T2 上的插入。
假设 T1 和 T2 都有 IDENTITY 列,@@IDENTITY 和 SCOPE_IDENTITY 将在 T1 上的 INSERT 语句的最后返回不同的值。
@@IDENTITY 返回插入到当前会话中任何作用域内的最后一个 IDENTITY 列值,该值是插入 T2 中的值。
SCOPE_IDENTITY() 返回插入 T1 中的 IDENTITY 值,该值是发生在相同作用域中的最后一个 INSERT。如果在作用域中发生插入语句到标识列之前唤醒调用 SCOPE_IDENTITY() 函数,则该函数将返回 NULL 值。
而IDENT_CURRENT('T1') 和 IDENT_CURRENT('T2') 返回的值分别是这两个表最后自增的值。