我参与了一个数据迁移项目.当我尝试将数据从一个表插入另一个表(SQL Server 2005)时,我收到以下错误:
消息8152,级别16,状态13,行1
字符串或二进制数据将被截断.
源数据列与数据类型匹配,并且在目标表列的长度定义内,因此我不知道可能导致此错误的原因.
总之,我有一个很大的(不可避免的)动态SQL查询.由于选择标准中的字段数,包含动态SQL的字符串增长超过4000个字符.现在,我知道有一个4000最大值设置NVARCHAR(MAX),但查看Server Profiler中执行的SQL语句
DELARE @SQL NVARCHAR(MAX);
SET @SQL = 'SomeMassiveString > 4000 chars...';
EXEC(@SQL);
GO
Run Code Online (Sandbox Code Playgroud)
似乎工作(!?),对于另一个同样大的查询,它会抛出一个与此4000限制(!?)相关的错误,它基本上修剪了这个4000限制之后的所有SQL,并且给我留下了语法错误.尽管这样的探查,它表示在这个动态的SQL查询全(!?).
究竟发生了什么,我应该将这个@SQL变量转换为VARCHAR并继续使用它吗?
谢谢你的时间.
PS.能够打印超过4000个字符来查看这些大查询也是很好的.以下限制为4000
SELECT CONVERT(XML, @SQL);
PRINT(@SQL);
Run Code Online (Sandbox Code Playgroud)
还有其他很酷的方式吗?
sql sql-server variables string-concatenation sql-server-2008
从asp.net Web表单调用API非常简单.
WebClient wc = new WebClient();
string urlData = wc.DownloadString("http://xxx.xxx.xx.xx/sssss/getResponse.do?ID=testing");
Run Code Online (Sandbox Code Playgroud)
但我们可以从Sql server存储过程调用API.
如果是,那么我们如何从Sql server存储过程调用API,以及如何获得API响应.
我有一个SQL Server数据表,它在其中一个列中存储JSON字符串.JSON字符串是序列化的.net对象,数据通常超过4000个字符.
我有一个简单的存储过程,我用它来检索数据:
@StageID int,
@Description varchar(250) = null OUTPUT,
@Program nvarchar(max) = null OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT @Program = StageProgram, @Description = Description
FROM StageProgram
WHERE StageID = @StageID;
RETURN 0;
END
Run Code Online (Sandbox Code Playgroud)
我正在使用nvarchar(max)列的数据类型.当我将.net对象序列化为JSON并使用Dapper将其写入数据库时,我发现完整的字符串正确存储在数据库中.
但是,当我尝试检索字符串时,我发现它被修剪为4000个字符,丢弃其余的数据.
这是相关代码:
DynamicParameters p = new DynamicParameters();
p.Add("@StageID", Properties.Settings.Default.StageID, DbType.Int32, ParameterDirection.Input);
p.Add("@Description", "", DbType.String, direction: ParameterDirection.Output);
p.Add("@Program", "", DbType.String, direction: ParameterDirection.Output);
p.Add("@ReturnValue", DbType.Int32, direction: ParameterDirection.ReturnValue);
try
{
int stageID = Properties.Settings.Default.StageID;
connection.Execute(sql, p, commandType: CommandType.StoredProcedure);
json = p.Get<string>("@Program");
int r = …Run Code Online (Sandbox Code Playgroud) 我们其中一个数据库的用户正在尝试向SQL Server 2005数据库提交UPDATE查询,并且文本意外被截断.
被截断的字段是VARBINARY(MAX),用于存储HTML文本.
查询大致是:
UPDATE Story
SET mainText = CONVERT (VARBINARY (MAX), '[...5000 chars of text...]'
+ char(47) + char(47)
+ '[...3000 chars of text...]'
+ char(47) + char(47)
+ '[...5000 chars of text...]')
WHERE storyId = 123456
Run Code Online (Sandbox Code Playgroud)
我在一些实验后发现的是,当我删除字符串连接时,查询按预期工作,并且字段不会被截断.
我能够通过将每个单独的字符串包装在CAST到VARCHAR(MAX)中来解决限制并保持连接,因此如果用户觉得需要使用char(),则有一个选项.
我认为,无论何时使用连接运算符,都会发生VARCHAR的隐式转换,并且隐式转换似乎仅限于VARCHAR(8000)而不是VARCHAR(MAX).因此,在将字符串发送到CONVERT函数之前,它已经被截断为8000个字符.
如果我是对的,有没有办法改变这种行为?
如果没有办法改变行为,除了CAST之外还有另一种方法可以解决这个问题吗?
通过 SSMS 调用 REST 服务确实不是一个好主意。
顺便说一句,自从微软创建了存储过程 sp_OAMethod,甚至 Red Gate 的 Phil Factor向我们展示了如何使用它,我想试一试。
我想将 OpenStreetMap 中的一些数据直接导入 MSSQL,所以我从这里复制了一个很好的查询,并根据我的意愿进行了调整。
在这个例子中,我将返回纳尔逊的所有电影院:
DECLARE @obj AS INT
DECLARE @Uri AS NVARCHAR(4000)
DECLARE @Response AS VARCHAR(8000)
SET @Uri = 'http://overpass-api.de/api/interpreter?data=area[name="Nelson"]->.a;(node(area.a)[amenity=cinema];way(area.a)[amenity=cinema];rel(area.a)[amenity=cinema];);out;'
EXEC sp_OACreate 'MSXML2.ServerXMLHttp.3.0', @obj OUT
EXEC sp_OAMethod @obj, 'open', NULL, 'GET', @Uri, false
EXEC sp_OAMethod @obj, 'send'
EXEC sp_OAGetProperty @obj, 'ResponseText', @Response OUTPUT
SELECT @Response [response]
EXEC sp_OADestroy @obj
Run Code Online (Sandbox Code Playgroud)
很好很简单,我可以在 Postman 和 SSMS 中看到 REST 调用响应:
当我尝试从 …
sql-server ×4
t-sql ×2
api ×1
c# ×1
dapper ×1
json ×1
migration ×1
rest ×1
sql ×1
sqldatatypes ×1
ssms ×1
varcharmax ×1
variables ×1