#####如何知道datatable中,每一列为数字类型时的小数位数??

tongki 2010-02-09 12:15:06
在Fill后,如何知道datatable中,每一列为数字类型时的小数位数??

VB6中,可以通过recordSet来获取。但Datatable.Columns[i]中,好像没有这个小数位数的属性?
...全文
1488 44 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
44 条回复
切换为时间正序
请发表友善的回复…
发表回复
tongki 2010-02-22
  • 打赏
  • 举报
回复
用GetSchemaTable是个好办法,稍微改动一下qldsrx(青龙白虎)的代码。
只是这个办法要求改变以前的SQLHelper,以及多转一个SchemaTable参数给表格控制对象。

测试代码如下:

public partial class Form2 : Form
{
private DataTable dtSchema = new DataTable();
public Form2()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
DataTable dt = ExecuteDataTableAndSchema("select * from Cg_PurSort", null, CommandType.Text, "myTable", out dtSchema);

string s = "";
for (int i = 0; i < dtSchema.Rows.Count; i++)
{
//for (int j = 0; j < dtSchema.Columns.Count; j++)
//{
// s += dtSchema.Columns[j].ToString(); ;
//}
s += dtSchema.Rows[i]["ColumnName"].ToString() + "小数位:" + dtSchema.Rows[i]["NumericScale"].ToString();
s += "\r\n";
}

MessageBox.Show(s);
}


public static IDbConnection GetConnection()
{
IDbConnection connection = null;

if (connection == null)//判断连接是否为空
{
connection = new SqlConnection();

connection.ConnectionString = "server=.;user id=sa;pwd=;database=C1Grid";//连接数据库的字符串 }

if (connection.State == ConnectionState.Closed)
{
connection.Open();//打开数据库连接

}
}

return connection;
}

/// <summary>
/// 执行一个 SQL 语句,返回一个数据表带表结构信息(传递连接)
/// </summary>
public static DataTable ExecuteDataTableAndSchema(string sqltext, Dictionary<string, object> parameters, CommandType ctyp, IDbConnection conn, string tableName, out DataTable dtSchema)
{
DataTable dt = null;
using (IDbCommand cmd = conn.CreateCommand())
{
cmd.Connection = conn;
cmd.CommandType = ctyp;
cmd.CommandText = sqltext;
if (parameters != null)
foreach (KeyValuePair<string, object> p in parameters)
{
IDataParameter idparam = cmd.CreateParameter();
idparam.ParameterName = p.Key;
idparam.Value = p.Value;
cmd.Parameters.Add(idparam);
}

using (IDataReader idr = cmd.ExecuteReader())
{
dtSchema = idr.GetSchemaTable();
dt = new DataTable(tableName);
dt.Load(idr);
}
}
return dt;
}

/// <summary>
/// 执行一个 SQL 语句,返回一个数据表带表结构信息(传递连接名)
/// </summary>
public static DataTable ExecuteDataTableAndSchema(string sqltext, Dictionary<string, object> parameters, CommandType ctyp, string tableName, out DataTable dtSchema)
{
using (IDbConnection conn = GetConnection())
{
return ExecuteDataTableAndSchema(sqltext, parameters, ctyp, conn,tableName, out dtSchema);
}
}

}
toxuecheng111 2010-02-22
  • 打赏
  • 举报
回复
学习了。。。。。。。。
tongki 2010-02-22
  • 打赏
  • 举报
回复
感谢qldsrx(青龙白虎),放假刚回来。我试试
flyerwing 2010-02-12
  • 打赏
  • 举报
回复
引用 7 楼 loginczh 的回复:
显示的时候TOString("F5")表示后面保留5位小数点 F1 是1位 F2 2位 以此类推

需要这么搞地
就是忘了不进行类型转换能不能搞通了!
qldsrx 2010-02-12
  • 打赏
  • 举报
回复
引用 37 楼 lzsh0622 的回复:
引用 36 楼 tongki_8 的回复:几乎所有的报表都是通过存储过程返回的。只是如果通过ado6.0的recordset可以获得,而不是ado.net没有recordset,如果DataTable没有存储列的数据精度信息,看来这个问题就很难解决了

直接查询出DataTable,也没有完整的结构信息.

我用过列的宽度信息,也是通过通过执行两次select语句完成的。

你的这个做法倒是给我了启发,其实也不用两次select语句,一次即可完成,只要稍作改动即可。
分享下我的DBManager中获取DataTable的函数,添加了Schema的获取。

public static IDbConnection GetConnection(string name)
{
IDbConnection connection = null;
string connectionString = ConfigurationManager.ConnectionStrings[name].ConnectionString;
string providerName = ConfigurationManager.ConnectionStrings[name].ProviderName;

if (providerName == "System.Data.SqlClient")
{
connection = new SqlConnection(connectionString);
}
else if (providerName == "System.Data.OracleClient")
{
connection = new OracleConnection(connectionString);
}
connection.Open();
return connection;
}

/// <summary>
/// 执行一个 SQL 语句,返回一个数据表带表结构信息(传递连接)
/// </summary>
public static DataTable ExecuteDataTableAndSchema(string sqltext, Dictionary<string, object> parameters, CommandType ctyp, IDbConnection conn, List<string> oracleCursors, out DataTable dtSchema)
{
DataTable dt = null;
using (IDbCommand cmd = conn.CreateCommand())
{
cmd.Connection = conn;
cmd.CommandType = ctyp;
cmd.CommandText = sqltext;
if (parameters != null)
foreach (KeyValuePair<string, object> p in parameters)
{
IDataParameter idparam = cmd.CreateParameter();
idparam.ParameterName = p.Key;
idparam.Value = p.Value;
cmd.Parameters.Add(idparam);
}
if (oracleCursors != null)
foreach (var oracleCursor in oracleCursors)
{
cmd.Parameters.Add(new OracleParameter(oracleCursor, OracleType.Cursor) { Direction = ParameterDirection.Output });
}
using (IDataReader idr = cmd.ExecuteReader())
{
dtSchema = idr.GetSchemaTable();
dt = new DataTable("Table1");
dt.Load(idr);
}
}
return dt;
}

/// <summary>
/// 执行一个 SQL 语句,返回一个数据表带表结构信息(传递连接名)
/// </summary>
public static DataTable ExecuteDataTableAndSchema(string sqltext, Dictionary<string, object> parameters, CommandType ctyp, string dbname, List<string> oracleCursors, out DataTable dtSchema)
{
using (IDbConnection conn = GetConnection(dbname))
{
return ExecuteDataTableAndSchema(sqltext, parameters, ctyp, conn, oracleCursors, out dtSchema);
}
}

这里的参数之所以用Dictionary<string, object> parameters,是为了通用化,在任何数据库下使用,同时方便了序列化。
oracleCursors是Oracle存储过程专用的,用不到可以为null。
既然要用到这个方法,dtSchema肯定是要给个变量接收的啦,里面存放了数据结构。
zhouwei7682719 2010-02-12
  • 打赏
  • 举报
回复
天天向上,得好好学习!
xray2005 2010-02-09
  • 打赏
  • 举报
回复
ToString("F3");//小数点后3位
小学码农 2010-02-09
  • 打赏
  • 举报
回复
比如:100.12 TOString(“F5”)后 为 100.12000
小学码农 2010-02-09
  • 打赏
  • 举报
回复
显示的时候TOString("F5")表示后面保留5位小数点 F1 是1位 F2 2位 以此类推
tongki 2010-02-09
  • 打赏
  • 举报
回复
col1 col2 col3
1 255.1 1000.02
1.2 30 201.256
8 58.21 3333.1

以上的样子出来后,当然通过表格格式设置,可以处理为以下样子,但我想得到列的小数位数后,去自动默认处理,除非客户再另行设置显示格式:
col1 col2 col3
1.0 255.10 1000.020
1.2 30.00 201.256
8.0 58.21 3333.100
Snowdust 2010-02-09
  • 打赏
  • 举报
回复
比如数据库中某字段类型为numberic(9, 4),有这些数据:
1.2000
1.2300
1.2340
1.0000
楼主想显示成什么样子?
QQ450659882 2010-02-09
  • 打赏
  • 举报
回复
关注中!不知道楼主想要做到什么效果
tongki 2010-02-09
  • 打赏
  • 举报
回复
引用 1 楼 snowdust 的回复:
你可以不管这个位数,在显示的时候格式化就行了。


嗯,一般情况下是不用理它。但现在我要在表格中自动格式化显示格式,由于涉及到1位、2位或3位不等的小数位时,自动根据实际数据的小数位数进行格式化显示并向右对齐。

这样的话,客户就可以在大多数时候省掉手工设置格式的工作,得到比较高的满意度,尤其在报表比较多的时候。
tianliang1 2010-02-09
  • 打赏
  • 举报
回复
好好学习,天天向上。
Snowdust 2010-02-09
  • 打赏
  • 举报
回复
你可以不管这个位数,在显示的时候格式化就行了。
lzsh0622 2010-02-09
  • 打赏
  • 举报
回复
引用 36 楼 tongki_8 的回复:
几乎所有的报表都是通过存储过程返回的。只是如果通过ado6.0的recordset可以获得,而不是ado.net没有recordset,如果DataTable没有存储列的数据精度信息,看来这个问题就很难解决了


直接查询出DataTable,也没有完整的结构信息.

我用过列的宽度信息,也是通过通过执行两次select语句完成的。
tongki 2010-02-09
  • 打赏
  • 举报
回复
引用 35 楼 lzsh0622 的回复:
引用 31 楼 tongki_8 的回复:嗯,以上方式可以从表或视图取得字段信息。但如果结果集是由存储过程返回的,如何处理?

这种方法可以独立使用,对应原始表的数据类型。与存储过程没关系。

不能依靠存储过程的返回结果,有可能在存储过程中已经改变了数据精度,甚至改变了数据类型。


几乎所有的报表都是通过存储过程返回的。只是如果通过ado6.0的recordset可以获得,而不是ado.net没有recordset,如果DataTable没有存储列的数据精度信息,看来这个问题就很难解决了
lzsh0622 2010-02-09
  • 打赏
  • 举报
回复
引用 31 楼 tongki_8 的回复:
嗯,以上方式可以从表或视图取得字段信息。但如果结果集是由存储过程返回的,如何处理?


这种方法可以独立使用,对应原始表的数据类型。与存储过程没关系。

不能依靠存储过程的返回结果,有可能在存储过程中已经改变了数据精度,甚至改变了数据类型。
wxm3630478 2010-02-09
  • 打赏
  • 举报
回复
//搞错了string
string a = "12345.10000";
string d = Convert.ToDouble(a).ToString("0.00");
//输出12345.10
string d = Convert.ToDouble(a).ToString("0.000");
//输出12345.100
string a = "1.10000";
string d = Convert.ToDouble(a).ToString("00.00");//输出01.10
wxm3630478 2010-02-09
  • 打赏
  • 举报
回复

string a = "12345.10000";
double d = Convert.ToDouble(a).ToString("0.00");
//输出12345.10
double d = Convert.ToDouble(a).ToString("0.000");
//输出12345.100
string a = "1.10000";
double d = Convert.ToDouble(a).ToString("00.00");//输出01.10
加载更多回复(23)

111,098

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧