Microsoft SQL Server 2000连接Sybase Adaptive Enterprise Server 12.5

一、OLE方式链接
一般的在ADO连接串生成工具中生成的串如下:
Provider=Sybase.ASEOLEDBProvider.2;Initial Catalog=数据库;Password=密码;User ID=用户名;Data Source=服务器;Extended Properties=””;Server Name=服务器;Network Protocol=Winsock;Server Port Address=端口;HA Server Name=””;HA Server Port Address=””;Character Set=””;Language=””;Application Name=””;Optimize Prepare=Partial;Select Method=Direct;Raise Error Behavior=MS Compatible;Print Statement Behavior=MS Compatible;Extended ErrorInfo=FALSE;Stored Proc Row Count=Last Statement Only;WorkStation ID=””;Row Cache Size=50;Enable Quoted Identifiers=0;Packet Size=1;Default Length For Long Data=1024;UseSybaseLDAP=False;SybaseLDAPURL=””;SybaseServerName=389;UseLDAPHAServer=0;Use SSL=0;Trusted Root File Name=””;Interfaces File=””;Interfaces File Server Name=””;EnableSPColumnTypes=True;TruncateTimeTypeFractions=1
实在是太长了。

在这篇文章中我们可以得到一个短串:
Sybase ASE OLE DB Provider Connection String
Provider=Sybase.ASEOLEDBProvider;Srvr=myASEserver,5000;Catalog=myDataBase;User Id=myUsername;Password=myPassword;

Provider=Sybase.ASEOLEDBProvider;Server Name=myASEserver,5000;Initial Catalog=myDataBase;User Id=myUsername;Password=myPassword;

更多的连接串信息可以参考 ConnectionStrings
二、视图方式透过访问
实验内容:
1. 采用查询建立的视图
create view q_testtable as select * from Q.qthdsj.dbo.testtable

select * from Q.qthdsj.dbo.testtable

select * from q_testtable

SELECT q_testtable.a1 , q_testtable.a2 FROM q_testtable

select a1, a2 from q_testtable

存在查询返回一条的问题。就是查询应该返回多条,但实际上只返回了一条。如图:

2. 采用openquery建立的视图
create view v_testtable as
select * from openquery (q,’select * from dbo.testtable’)

select a1, a2 from v_testtable

实际上,这个查询应该返回的内容非常多。如图:


问题解决。

三、结论
这个问题是一个实际需要。虽然如果是我来做肯定不用这种方式。好处是显而易见的,你不需要在你的电脑上安装Sybase Client。也不需要导入导出数据。对于客户端,它还没有什么性能压力,压力只存在于Server端。坏处当然也是非常多的。首先是性能一般,甚至如果你的Server性能不怎么样的话还是不要使用了。另外,它的变态设置,以及Sybase驱动的问题影响了配置乐趣。

四、Sybase作为一个当年十分红火的数据库,自从将SQL Server卖出给微软之处走过的路说明,它已经风光不再。SAP的收购难言是忧是喜。因为在这个测试中,Sybase 12.5系列(虽然现在已经是15了,但是还有很多人在用12.5这个版本)的驱动显然问题很多,甚至让我对MySQL和PostgreSQL的感觉又提升了一层。没有良好商业性支持,一个又一个的版本更新也难掩垂暮的老态。多年之后,难道Sybase可言的只有Sybase PowerBuilder和PowerDesigner? 还记得当年一个Sybase的朋友说过一句“做工具,微软怎么比得上PowerBuilder”。斯是当年,今忆垂泪,唏嘘不已。

参考文章:
1. Issue with Sql Server to Sybase linked server using stored procedure

SQL Server,一个自定义字符串转日期函数

读别人的程序能学到好多东西。好的学习,坏的学习如何改进,实在难以入目的,就引以为戒。

比如这个,日期不用datetime类型保存,用nvarchar,倒是可以,但是完全依赖系统设置在系统移植的时候真是难呐。
这两个一个是英文环境一个是中文环境的日期值:
Oct 1 2009 9:19AM
10 1 2009 9:19AM

没办法写了个函数来转:
[sourcecode language=”sql”]
create function uf_ctod(@datestr varchar(20))
returns datetime
as
begin
declare @st char(2)
declare @rd datetime
declare @s2 char(3)
declare @s3 varchar(20)
declare @sf varchar(20)

set @st = substring(@datestr, 1, 2)
if isnumeric(@st) =1 begin
set @rd = convert(datetime, @datestr, 109)
end else begin
set @s2 = substring(@datestr, 1, 3)
set @sf = substring(@datestr, 4, len(@datestr)-3)
select @s3 = case @s2
when ‘Jan’ then ‘1’
when ‘Feb’ then ‘2’
when ‘Mar’ then ‘3’
when ‘Apr’ then ‘4’
when ‘May’ then ‘5’
when ‘Jun’ then ‘6’
when ‘Jul’ then ‘7’
when ‘Aug’ then ‘8’
when ‘Sep’ then ‘9’
when ‘Oct’ then ’10’
when ‘Nov’ then ’11’
when ‘Dec’ then ’12’ end
set @sf = @s3 + @sf
set @rd = convert(datetime, @sf, 109)
end
return(@rd)
end
[/sourcecode]
再改进一点点:
[sourcecode language=”sql”]
create function uf_c2d(@datestr varchar(20))
returns datetime
begin
declare @rd datetime
select @rd =
case when isnumeric(substring(@datestr, 1, 2)) = 1 then
convert(datetime, @datestr, 109)
else
case substring(@datestr, 1, 3)
when ‘Jan’ then ‘1’
when ‘Feb’ then ‘2’
when ‘Mar’ then ‘3’
when ‘Apr’ then ‘4’
when ‘May’ then ‘5’
when ‘Jun’ then ‘6’
when ‘Jul’ then ‘7’
when ‘Aug’ then ‘8’
when ‘Sep’ then ‘9’
when ‘Oct’ then ’10’
when ‘Nov’ then ’11’
when ‘Dec’ then ’12’
end + substring(@datestr, 4, len(@datestr) -3)
end
return(@rd)
end
[/sourcecode]

SQL: 同期数据对比样例

结构
县区名称 月份 参保职工人数
ABC 200802 数量

Access版本:

SELECT * FROM (SELECT A.县区名称 AS 县区名称, A.月份 AS 去年同期, A.参保职工人数 AS 去年同期人数, B.月份 AS 今年日期, B.参保职工人数 AS 今年同期人数
FROM 月报数据 A, 月报数据 B
WHERE (A.县区名称=B.县区名称)) X
WHERE (CINT(MID(去年同期, 1, 4)) + 1 = CINT(MID(今年日期, 1, 4))) AND (MID(去年同期, 5, 2) = MID(今年日期, 5, 2))

SQL Server版本:
SELECT * FROM (SELECT A.县区名称 AS 县区名称, A.月份 AS 去年同期, A.参保职工人数 AS 去年同期人数, B.月份 AS 今年日期, B.参保职工人数 AS 今年同期人数
FROM 月报数据 A, 月报数据 B
WHERE (A.县区名称=B.县区名称)) X
WHERE DATEDIFF(m, SUBSTRING(去年同期, 1, 4) + ‘-‘ + SUBSTRING(去年同期, 5, 2) + ‘-01’,
SUBSTRING(今年日期, 1, 4) + ‘-‘ + SUBSTRING(今年日期, 5, 2) + ‘-01’) = 12

SQL重复值删除

1. 重复值的判定:

分组,统计数量,如:

SELECT 销售单位, COUNT(*) FROM 销售主表 GROUP BY 销售单位 HAVING COUNT(*) > 4

销售单位重复4次以上的才会显示出来。

2. 删除动作,比如将上面的消除掉

DELETE FROM 销售主表
WHERE 单位名称 IN (SELECT T.单位名称 FROM 销售主表 T GROUP BY T.单位名称 HAVING COUNT(*) > 4)

3. 另一种方式,一列和多列的情况,此处简化了,只删除了重复的,就是多于1次的记录

一列:
DELETE 销售主表
FROM (SELECT T.单位名称 FROM 销售主表 T GROUP BY T.单位名称 HAVING COUNT(*) > 1) AS T1
WHERE T1.单位名称 = 销售主表.单位名称

多列:

DELETE 销售主表 FROM (SELECT T.销售单位 FROM 销售主表 T GROUP BY T.销售单位 HAVING COUNT(*) > 1) AS T1 WHERE T1.销售单位 = 销售主表.销售单位 ….